您的位置:首页> 前端教程> TS教程

TypeScript 类型兼容

2019-5-18 18:17| 作者: admin| 查看: 1008| 评论: 0|来自: 蚂蚁部落

TypeScript类型兼容性是基于结构子类型的;结构类型只使用其成员来描述类型。

代码实例:

[typescript] 纯文本查看 复制代码
interface Antzone {
  webName: string;
}
 
class Antzone {
  webName: string;
}
 
let ant: Antzone;
ant = new Antzone();

代码赋值成立;如果是在C#等典型的面向对象语言中,代码不可能正确。

如果S类型数据要赋值给T类型成功,那么S类型数据相对于T类型而言,不能具有额外的属性,同时T中的每个属性都能在S中找到对应的属性。代码实例如下:

[typescript] 纯文本查看 复制代码
interface Antzone {
  webName: string;
  age:number
}
 
let ant: Antzone={
  webName:"蚂蚁部落",
  age:4
}

上面代码赋值成功,首先对象直接量相较接口而言,没有额外属性,同时接口中的每一个属性都能在对象直接量中找到对应的属性,且类型匹配。再来看一段代码实例:

[typescript] 纯文本查看 复制代码
interface Antzone {
  webName: string;
  age:number
}
let ant={
  webName:"蚂蚁部落",
  age:4,
  address:"青岛市南区"
}
let antzone:Antzone=ant;

很明显ant具有一个额外的属性address,但是赋值同样会成功。官方文档解释如下:

如果认为S相对于T具有额外属性,首先S是一个fresh object literal type,并且S中含有T不期望存在的属性。

fresh object literal type可以直白的理解一个直接的对象直接量,如下代码:

[JavaScript] 纯文本查看 复制代码
let ant: Antzone={
  webName:"蚂蚁部落",
  age:4
}

上面代码中对象直接量直接被赋值给目标类型变量,这时候它就是一个fresh类型。

fresh object literal types失去freshness情况如下:

(1).fresh类型数据被widened,结果数据的类型失去freshness。

(2).类型断言后产生的数据类型类型失去freshness。

关于Widened 类型可以参阅TypeScript Widened 类型一章节。

关于类型断言可以参阅TypeScript 类型断言一章节。

再来看前面的代码:

[typescript] 纯文本查看 复制代码
let ant={
  webName:"蚂蚁部落",
  age:4,
  address:"青岛市南区"
}

对象直接量首先赋值给ant变量,ant的类型是由直接量推断而来,是fresh对象直接量类型的Widened形式。

下面再罗列一下常见S可以赋值给T的情况:

(1).S或者T有一个是Any类型:

因为Any类型可以赋值给任意其他类型,也可以被其他任意类型赋值(never类型除外):

[typescript] 纯文本查看 复制代码
let any:any=5;
let num:number=any;

关于Any类型可以参阅TypeScript Any 类型一章节。

(2).S是Undefined类型:

在默认情况下,Undefined类型数据可以赋值给其他类型数据,Never类型除外之外:

[typescript] 纯文本查看 复制代码
let num:number=undefined;

当指定--strictNullChecks标记,null和undefined只能赋值给void和它们各自。

(3).S是Null类型:

在默认情况下,Undefined类型数据可以赋值给其他类型数据,Never类型除外之外:

[typescript] 纯文本查看 复制代码
let num:number=null;

当指定--strictNullChecks标记,null和undefined只能赋值给void和它们各自。

关于Null和Undefined类型可以参阅TypeScript Null和Undefined 类型一章节。

(4).S或者T是枚举类型:

数字和枚举之间是相互兼容的,但是不同的枚举之间是不兼容的。

[typescript] 纯文本查看 复制代码
enum Color {
  blue,
  red,
  yellow
}
let num:number=Color.blue;

枚举成员值可以赋值给数值类型。

[typescript] 纯文本查看 复制代码
enum Color {
  blue,
  red,
  yellow
}
let ant:Color=5;

数字可以赋值给枚举类型数据。

[typescript] 纯文本查看 复制代码
enum Color {
  blue,
  red,
  yellow
}
Color.blue=1;

不能给枚举成员赋值,因为它们是常数。

(5).如果S是联合类型,并且每一个类型可以赋值给T类型:

[typescript] 纯文本查看 复制代码
let ant:"蚂蚁部落"|"青岛市南区"="蚂蚁部落";
let str:string=ant;

ant是联合类型数据,并且组成联合类型的每一个字符串字面类型都可以赋值给字符串类型变量。

(6).如果S是交叉类型,那么至少有一个类型可以赋值给T:

[typescript] 纯文本查看 复制代码
interface One{
  webName:string;
}
interface Two{
  age:number;
}
 
interface Itest{
  age:number;
}
type ant=One&Two;
 
let antzone:ant={
  webName:"蚂蚁部落",
  age:4
}
 
let test:Itest=antzone;

(7).如果T是一个联合类型,那么S只要可赋值给组成联合类型的任意一个类型:

[typescript] 纯文本查看 复制代码
type tp=string|number;
let ant:tp="蚂蚁部落";

(8).如果是T是交叉类型,那么S(非fresh type)需要可以赋值给组成交叉类型的每一个类型:

[typescript] 纯文本查看 复制代码
interface One{
  webName:string;
}
 
interface Two{
  age:number;
}
 
type ant=One&Two;
 
let antzone:ant={
  webName:"蚂蚁部落",
  age:4
}

还有函数、类和枚举的兼容,可以参阅后续相关章节,这里就不再介绍了。


鲜花

握手

雷人

路过

鸡蛋

最新评论

返回顶部