欢送关注公众号
如果你用过TypeScript,肯定接触过Interface
和Type
。
5秒钟思考一下,他俩有什么雷同和不同?
如果你对他们的不同无所不知,那么请持续往下看。
如果咱们申明一个Point
类型,能够通过以下两种形式都会达到咱们想要的后果:
interface Point { x: number; y: number;}
或者
type Point = { x: number; y: number;}
下面的列子没有体现出 interface
和 type
之间的不同。
让咱们进一步摸索。
TypeScript的类型包含原始数据类型、对象类型、高级类型等。
原始数据类型包含:boolean
、number
、string
、null
、undefined
以及ES6中的新类型 Symbol
和ES10中的 BigInt
。
高级类型:联结类型(Unions Type),泛型(Generics)
联结类型(Unions Type)
联结类型(Union Types)示意取值能够为多种类型中的一种。
举个栗子:
function printId(id: number | string) { console.log("Your ID is: " + id);}// OKprintId(101);// OKprintId("202");// ErrorprintId({ myID: 22342 });//抛出错误信息 //Argument of type '{ myID: number; }' is not assignable to parameter of type 'string | number'.// Type '{ myID: number; }' is not assignable to type 'number'.
下面例子中如果删除传入一个对象 会抛出异样,不能把 '{ myID: number; }'
赋值给 string或者number类型。
function printId(id: number | string) { console.log(id.toUpperCase());}//ErrorProperty 'toUpperCase' does not exist on type 'string | number'. Property 'toUpperCase' does not exist on type 'number'.
咱们来剖析一下下面的报错,只有string
类型的字符串有toUpperCase
属性。number
类型没有toUpperCase
属性,ts类型推断的时候就会报错。感觉TypeScript很智能,能够提前感知谬误。
如果想反对参数 既是 string类型,又是number类型,须要改良一下。如下:
function printId(id: number | string) { if (typeof id === "string") { // In this branch, id is of type 'string' console.log(id.toUpperCase()); } else { // Here, id is of type 'number' console.log(id); }}
类型别名(Type Aliases)
类型别名是指给一个类型起个新名字。留神这里不是定义一个新的类型,而是给了一个新的名字。
类型别名罕用于 原始类型,联结类型(Unions Type)
type Point = { x: number; y: number;};// Exactly the same as the earlier examplefunction printCoord(pt: Point) { console.log("The coordinate's x value is " + pt.x); console.log("The coordinate's y value is " + pt.y);}printCoord({ x: 100, y: 100 });
联结类型
type ID = number | string;
type UserInputSanitizedString = string;function sanitizeInput(str: string): UserInputSanitizedString { return "inputcontent"}
类型别名是指给一个类型起个新名字,所以上面 string和UserInputSanitizedString都是雷同类型
对象的类型—接口
在 TypeScript 中,咱们应用接口(Interfaces)来定义对象类型。相比类型别名,Interfaces仅用于 对象类型。
继承—extend
interface
和 type
都反对继承,并且 interface
能够继承 type
,type
又能够继承interface
,只是语法不一样。举例说明:
1.interface
extend interface
interface PartialPointX { x: number; }interface Point extends PartialPointX { y: number; }
2.interface
extend type
type PartialPointX = { x: number; };interface Point extends PartialPointX { y: number; }
type
&type
type PartialPointX = { x: number; };// 这里继承应用的是 & type Point = PartialPointX & { y: number; };
type
&interface
interface PartialPointX { x: number; }type Point = PartialPointX & { y: number; };
实现—Implements
一个class能够实现(implement) interface 和 type,但不能够实现(implement)一个联结类型(unions type)
interface Point { x: number; y: number;}class SomePoint implements Point { x = 1; y = 2;}type AnotherPoint = { x: number; y: number;};class SomePoint2 implements AnotherPoint { x = 1; y = 2;}type PartialPoint = { x: number; } | { y: number; };//不能实现一个联结类型,上面代码将会抛出异样class SomePartialPoint implements PartialPoint { x = 1; y = 2;}
申明合并—Declaration Merging
TypeScript在编译的时候,会将名字雷同的interface
合并成一个接口,然而 type
就不行 。
看一个简略的例子,interface名字一样,然而 属性名不同
interface Box { height: number; width: number;}interface Box { scale: number;}let box: Box = { height: 5, width: 6, scale: 10 };
下面的例子 把两个Box的类型合并成了上面后果
interface Box { height: number; width: number; scale: number;}let box: Box = { height: 5, width: 6, scale: 10 };
再来看一个例子,interface名字一样,然而 属性名也一样
interface Cloner { clone(animal: Animal): Animal;}interface Cloner { clone(animal: Sheep): Sheep;}interface Cloner { clone(animal: Dog): Dog; clone(animal: Cat): Cat;}
三个 Cloner的interface 合并之后的后果如下:
interface Cloner { clone(animal: Dog): Dog; clone(animal: Cat): Cat; clone(animal: Sheep): Sheep; clone(animal: Animal): Animal;}
仔细观察,合并之后,第三个接口的属性排在最后面,优先级最高。这个肯定要留神
Interface
和Type
如何抉择呢?
下面内容,咱们比拟了 Interface
和Type
两者之间的相同点和不同点。接下来总结一下。
对于库中类型或第三方库类型,定义公共 API ,应应用接口来提供申明合并性能。
除此之外,咱们轻易抉择,然而要保障代码的一致性。
参考资料
https://www.typescriptlang.or...
https://javascript.plainengli...