心绪 發表於 2020-6-9 22:31:00

TypeScript类型检查机制

<p>类型检查机制:TypeScript编译器在做类型检查时,所秉承的一些原则。</p>
<p>作用:辅助开发,提高开发效率。</p>
<h1>一、类型推断</h1>
<p>不需要指定变量的类型(函数的返回值类型),TypeScript可以根据某些规则自动地为其推断出一个类型。</p>
<h2>1,基础类型推断</h2>
<div class="cnblogs_code">
<pre>let a <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">let a: any</span>
let b = 1 <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">let b: number</span>
let c = [] <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">let c: any[]</span>
let c2 = <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">let c2: number[]</span>

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">设置函数默认参数</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">确定函数返回值的时候</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">let function1: (x?: number) =&gt; number</span>
let function1 =(x=1)=&gt; x+1<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">x=&gt;number //function1返回number类型</span></pre>
</div>
<h2>2,最佳通用类型推断</h2>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">最佳通用类型推断</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">从多个类型推断出一个类型的时候,尽可能的兼容类型</span>
<span style="color: rgba(0, 0, 0, 1)">
let arr </span>= <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">let arr: (number | null)[]</span></pre>
</div>
<h2>3,上下文类型推断</h2>
<p>上面两种类型推断都是从右向左的推断,也就是根据表达式右侧的值推断表达式左边变量的类型。还有一种类型推断是从左到右。这就是上下文类型推断。</p>
<p>上下文类型推断通常发生在事件处理中。</p>
<div class="cnblogs_code">
<pre>window.onkeydown = (event)=&gt;<span style="color: rgba(0, 0, 0, 1)">{
    console.log(evevt.button)
}</span></pre>
</div>
<p>用类型断言</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">interface Foo{
    bar:number
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> let foo = {} as Foo</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> foo.bar =1;</span>

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">推荐</span>
let foo: Foo =<span style="color: rgba(0, 0, 0, 1)">{
    bar: </span>1<span style="color: rgba(0, 0, 0, 1)">
}</span></pre>
</div>
<h1>二、类型兼容性</h1>
<p>结构之间兼容:成员少的兼容成员多的</p>
<p>函数之间兼容:参数多的兼容参数少的</p>
<h2>&nbsp;1,接口兼容性</h2>
<p>属性少的兼容属性多的</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">类型兼容性</span><span style="color: rgba(0, 128, 0, 1)">
/*</span><span style="color: rgba(0, 128, 0, 1)">*
* X兼容Y:X(目标类型) = Y(源类型)
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">接口兼容性</span>
<span style="color: rgba(0, 0, 0, 1)"> interface X{
   a:any;
   b:any;
}

interface Y{
   a:any;
   b:any;
   c:any;
}

let x1:X </span>={a:1,b:2<span style="color: rgba(0, 0, 0, 1)">};
let y1:Y</span>={a:1,b:2,c:3<span style="color: rgba(0, 0, 0, 1)">}

x1 </span>= y1 <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">X可以兼容Y</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">y1 =x1 //Property 'c' is missing in type 'X' but required in type 'Y'.</span></pre>
</div>
<h2>2,函数的兼容性</h2>
<p>&nbsp;两个函数相互赋值的情况,即函数作为参数的情况。</p>
<p>1, 目标函数的参数个数一定要等于多于原函数的个数</p>
<p>函数中含义可选参数或者剩余参数的时候,也会遵循其他原则</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">1)参数个数</span>
let handler1 = (a:number) =&gt;<span style="color: rgba(0, 0, 0, 1)">{}
hof(handler1)
let handler2 </span>= (a:number, b:number) =&gt;<span style="color: rgba(0, 0, 0, 1)">{}
hof(handler2)
let handler3 </span>= (a:number, b:number, c:number) =&gt;<span style="color: rgba(0, 0, 0, 1)">{}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> hof(handler3) //类型“(a: number, b: number, c: number) =&gt; void”的参数不能赋给类型“Handler”的参数。</span>


<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">可选参数和剩余参数</span>
let functionA=(p1:number,p2:number)=&gt;{} <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">固定参数</span>
let functionB=(p1?:number,p2?:number)=&gt;{} <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">可选参数</span>
let functionC=(...args:number[])=&gt;{} <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">剩余参数</span>

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">1,固定参数可以兼容可选参数和剩余参数</span>
functionA=functionB <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">固定参数可以兼容可选参数</span>
functionA=functionC <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">固定参数可以兼容剩余参数</span>

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">2,可选参数不兼容固定参数和剩余参数</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> functionB = functionA//不能将类型“undefined”分配给类型“number”</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> functionB = functionC//不能将类型“undefined”分配给类型“number”</span>

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 可以通过设置 strictFunctionTypes: false来实现兼容</span>
</pre>
<div>
<div> //&nbsp;functionB&nbsp;=&nbsp;functionA</div>
<div> //&nbsp;functionB&nbsp;=&nbsp;functionC</div>
</div>
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">3,剩余参数可以兼容固定参数和可选参数</span>
functionC =<span style="color: rgba(0, 0, 0, 1)"> functionA
functionC </span>= functionB</pre>
</div>
<p>2,参数类型</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">2)参数类型</span>
let handler4 =(a:string) =&gt;<span style="color: rgba(0, 0, 0, 1)">{}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> hof(handler4)//类型不兼容,不能将类型“number”分配给类型“string”。</span>
<span style="color: rgba(0, 0, 0, 1)">
interface Point3D{
    x:number;
    y:number;
    z:number;
}
interface Point2D{
    x:number;
    y:number;
}
let p3d </span>=(point:Point3D) =&gt;<span style="color: rgba(0, 0, 0, 1)">{}
let p2d </span>=(point:Point2D) =&gt;<span style="color: rgba(0, 0, 0, 1)">{}
p3d </span>=<span style="color: rgba(0, 0, 0, 1)"> p2d;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> p2d = p3d; //不兼容 ////Property 'z' is missing in type 'Point2D' but required in type 'Point3D'.</span>


<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">对比接口的兼容性</span>
let i3d:Point3D = {x:1,y:1,z:1<span style="color: rgba(0, 0, 0, 1)">};
let i2d:Point2D </span>= {x:1,y:1<span style="color: rgba(0, 0, 0, 1)">};
i2d </span>=<span style="color: rgba(0, 0, 0, 1)"> i3d
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> i3d = i2d //不兼容 //Property 'z' is missing in type 'Point2D' but required in type 'Point3D'.</span></pre>
</div>
<p>3,返回值类型</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">3) 返回值类型</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">目标函数的返回值类型必须与源函数的返回值类型相同或为其子类型</span>
let rf1 = ()=&gt;({name:"Alice"<span style="color: rgba(0, 0, 0, 1)">});
let rf2 </span>= ()=&gt;({name:"Alice",location:"Beijing"<span style="color: rgba(0, 0, 0, 1)">});
rf1 </span>=<span style="color: rgba(0, 0, 0, 1)"> rf2;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> rf2 = rf1; //Property 'location' is missing in type '{ name: string; }' but required in type '{ name: string; location: string; }'.</span>

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">函数重载</span>

<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> overload(a:number,b:number):number
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> overload(a:string,b:string):string
</span><span style="color: rgba(0, 0, 255, 1)">function</span> overload(a:any,b:any):any {}</pre>
</div>
<p>函数重载:</p>
<p>重载列表中的函数是目标函数,具体实现是源函数,编译器查找重载列表,使用第一个匹配的定义执行执行函数。</p>
<h2>3,枚举的兼容性</h2>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">枚举类型</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">枚举类型和数值类型完全兼容</span>
<span style="color: rgba(0, 0, 0, 1)">enum Fruit {Apple, banana}
enum Color {Red, Yellow}
let fruit:Fruit.Apple </span>=4<span style="color: rgba(0, 0, 0, 1)">

let no:number </span>=<span style="color: rgba(0, 0, 0, 1)"> Fruit.Apple
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> let color:Color.Red = Fruit.Apple 枚举类型之间不兼容</span></pre>
</div>
<h2>4,类的兼容性</h2>
<p>&nbsp;静态成员和构造函数不参与两个类兼容性比较</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">类的兼容性</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">静态成员和构造函数不参与两个类的兼容性比较</span>
<span style="color: rgba(0, 0, 0, 1)">class A{
    constructor(p:number,q:number){}
    id:number </span>=1<span style="color: rgba(0, 0, 0, 1)">;</span>
<span style="color: rgba(0, 0, 0, 1)">}

class B{
    static s </span>=1<span style="color: rgba(0, 0, 0, 1)">;
    id:number </span>=2<span style="color: rgba(0, 0, 0, 1)">
    constructor(p:number){}</span>
<span style="color: rgba(0, 0, 0, 1)">}

let aa </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> A(1,2<span style="color: rgba(0, 0, 0, 1)">);
let bb </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> B(1<span style="color: rgba(0, 0, 0, 1)">);
aa </span>=<span style="color: rgba(0, 0, 0, 1)"> bb;
bb </span>=aa;</pre>
</div>
<p>如果类中有私有成员,两个类就不兼容了</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">类的兼容性</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">静态成员和构造函数不参与两个类的兼容性比较</span>
<span style="color: rgba(0, 0, 0, 1)">class A{
    constructor(p:number,q:number){}
    id:number </span>=1<span style="color: rgba(0, 0, 0, 1)">;
    private name:string </span>= ''<span style="color: rgba(0, 0, 0, 1)">
}

class B{
    static s </span>=1<span style="color: rgba(0, 0, 0, 1)">;
    id:number </span>=2<span style="color: rgba(0, 0, 0, 1)">
    constructor(p:number){}
    private name:string </span>= ''<span style="color: rgba(0, 0, 0, 1)">
}

let aa </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> A(1,2<span style="color: rgba(0, 0, 0, 1)">);
let bb </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> B(1<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> aa = bb; //不能将类型“B”分配给类型“A”。类型具有私有属性“name”的单独声明</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> bb =aa; //不能将类型“A”分配给类型“B”。类型具有私有属性“name”的单独声明</span></pre>
</div>
<p>类有私有成员的时候,只有父类和子类直接可以相互兼容</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">class A{
    constructor(p:number,q:number){}
    id:number </span>=1<span style="color: rgba(0, 0, 0, 1)">;
    private name:string </span>= ''<span style="color: rgba(0, 0, 0, 1)">
}

let aa </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> A(1,2<span style="color: rgba(0, 0, 0, 1)">);

class AA extends A{
}
let aaa </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> AA(1,2<span style="color: rgba(0, 0, 0, 1)">)
aa</span>=<span style="color: rgba(0, 0, 0, 1)">aaa
aaa </span>=aa</pre>
</div>
<h2>5,泛型的兼容性</h2>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">泛型的兼容性</span>
interface Empty&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">{
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> value:T //只有类型参数T被接口成员使用了以后才会影响泛型的兼容性</span>
<span style="color: rgba(0, 0, 0, 1)">}
let intObj1:Empty</span>&lt;number&gt; =<span style="color: rgba(0, 0, 0, 1)"> {}
let intObj2:Empty</span>&lt;string&gt; =<span style="color: rgba(0, 0, 0, 1)"> {}
intObj1 </span>= intObj2</pre>
</div>
<p>泛型函数</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">泛型函数</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">两个泛型函数定义相同,没有指定类型参数,它们之间也可以相互兼容</span>
let log1 = &lt;T&gt; (x:T):T=&gt;<span style="color: rgba(0, 0, 0, 1)">{
    console.log(</span>'x'<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> x;
}

let log2 </span>= &lt;U&gt; (x:U):U=&gt;<span style="color: rgba(0, 0, 0, 1)">{
    console.log(</span>'y'<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> x;
}
log1</span>= log2&nbsp;</pre>
</div>
<h1>三、类型保护机制</h1>
<p>&nbsp;因为不知道程序运行时会传入什么参数,所以得在每一处都加上类型断言。</p>
<p><img src="https://img2020.cnblogs.com/blog/315302/202006/315302-20200610085548051-2035945685.png"></p>
<div class="cnblogs_code"><img id="code_img_closed_743f443d-e6e9-494e-88c1-c79c5fec7cfa" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_743f443d-e6e9-494e-88c1-c79c5fec7cfa" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_743f443d-e6e9-494e-88c1-c79c5fec7cfa" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">enum Type {Strong, weak}

class Java{
    helloJava(){
      console.log(</span>"hello Java"<span style="color: rgba(0, 0, 0, 1)">)
    }
}

class JavaScript{
    helloJavaScript(){
      console.log(</span>"Hello JavaScript"<span style="color: rgba(0, 0, 0, 1)">);
    }
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">用类型断言解决报错</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> getLanguage(type:Type){
    let lang </span>= type===Type.Strong?<span style="color: rgba(0, 0, 255, 1)">new</span> Java():<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> JavaScript()
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">创建实例之后运行实例的打印的方法</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">((lang as Java).helloJava){
      (lang as Java).helloJava();
    }</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
      (lang as JavaScript).helloJavaScript()
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> lang
}

getLanguage(Type.Strong)</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>代码可读性差,类型保护机制来解决这个问题。</p>
<p>&nbsp;类型保护:TypeScript能够在特定的区块中保证变量属于某种确定的类型。</p>
<p>可以在此区块中放心地引用此类型的属性,或者调用此类型的方法。</p>
<p>4种创建特殊区块的方法。</p>
<h2>1、instanceof</h2>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> getLanguage(type:Type){
    let lang </span>= type===Type.Strong?<span style="color: rgba(0, 0, 255, 1)">new</span> Java():<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> JavaScript()
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 第一种 instanceof</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span>(lang <span style="color: rgba(0, 0, 255, 1)">instanceof</span><span style="color: rgba(0, 0, 0, 1)"> Java){
      lang.helloJava()
    }</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
      lang.helloJavaScript()
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> lang
}</span></pre>
</div>
<h2>2, in</h2>
<p>判断某个属性是否属于某个对象</p>
<p>在两个类中分别加入一个属性java和javascript</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">enum Type {Strong, weak}

class Java{
    helloJava(){
      console.log(</span>"hello Java"<span style="color: rgba(0, 0, 0, 1)">)
    }
    java :any
}

class JavaScript{
    helloJavaScript(){
      console.log(</span>"Hello JavaScript"<span style="color: rgba(0, 0, 0, 1)">);
    }
    javascript: any
}</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> getLanguage(type:Type){
    let lang </span>= type===Type.Strong?<span style="color: rgba(0, 0, 255, 1)">new</span> Java():<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> JavaScript()
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">第二种 in关键字,判断属性是否属于某个对象</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span>('java' <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> lang){
      lang.helloJava()
    }</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
      lang.helloJavaScript()
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> lang
}</span></pre>
</div>
<h2>3, typeof类型保护</h2>
<p>判断基本类型</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span> getLanguage(type:Type, x:string |<span style="color: rgba(0, 0, 0, 1)"> number){
    let lang </span>= type===Type.Strong?<span style="color: rgba(0, 0, 255, 1)">new</span> Java():<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> JavaScript()
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">第三种 typeof 判断基本类型</span>
    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">新加函数参数x类型是联合类型string | number</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(0, 0, 255, 1)">typeof</span> x === 'string'<span style="color: rgba(0, 0, 0, 1)">){
      x.length</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">调string类型的属性</span>
    }<span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
      x.toFixed() </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">调number类型的方法</span>
<span style="color: rgba(0, 0, 0, 1)">    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> lang
}</span></pre>
</div>
<h2>4,自定义类型保护函数</h2>
<p>通过创建类型保护函数isJava()判断对象的类型</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span> isJava(lang: Java |<span style="color: rgba(0, 0, 0, 1)"> JavaScript ):lang is Java{
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> (lang as Java).helloJava !==<span style="color: rgba(0, 0, 0, 1)"> undefined
}

</span><span style="color: rgba(0, 0, 255, 1)">function</span> getLanguage(type:Type, x:string |<span style="color: rgba(0, 0, 0, 1)"> number){
    let lang </span>= type===Type.Strong?<span style="color: rgba(0, 0, 255, 1)">new</span> Java():<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> JavaScript()

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">第四种 类型保护函数</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(isJava(lang)){
      lang.helloJava()
    }</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
      lang.helloJavaScript()
    }

    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> lang
}</span></pre>
</div>
<p>&nbsp;</p>

</div>
<div id="MySignature" role="contentinfo">
    <p><strong>如果觉得本文对您有帮助~可以<span style="display: none">支付宝(左)或</span>微信支持一下:</strong></p>
<br>
<p style="display: none"><strong>看到小伙伴打赏时给我写一些鼓励的话,真的非常感动,谢谢你们。</strong></p>
<br>
<p style="display: none"><strong>我开了个微信公众号(<span>第三个二维码</span>)用来分享自己的职场英语相关学习经验,感兴趣可以关注,我会不断更新~</strong></p><br>
<div class="pay_img"><img style="display: none" class="alipay" src="http://files.cnblogs.com/files/starof/starof_zfb.bmp" alt="支付宝打赏"><img src="http://files.cnblogs.com/files/starof/starof_wx.bmp" alt="微信打赏"><img style="display: none" src="https://files.cnblogs.com/files/starof/starof_gzh.bmp" alt="微信公众号"></div><br><br><br>
来源:https://www.cnblogs.com/starof/p/13050710.html
頁: [1]
查看完整版本: TypeScript类型检查机制