如果学习过一些js的话那么ts还是比较好上手的
简单来说,ts就是js的超集,ts有静态类型检查机制
静态类型检查:代码运行前进行检查
基本知识
类型声明
类型声明的写法,一律为在标识符后面添加“冒号 + 类型”
TypeScript 对五种原始类型分别提供了大写和小写两种类型。
- Boolean 和 boolean
- String 和 string
- Number 和 number
- BigInt 和 bigint
- Symbol 和 symbol
其中,大写类型同时包含包装对象和字面量两种情况,小写类型只包含字面量,不包含包装对象。
类型判断
对于没有给出的类型声明,ts会自动推断类型
常用的数据类型
| 类型 | 说明 |
|---|---|
| any | 类型表示没有任何限制,该类型的变量可以赋予任意类型的值。 |
| unknown | 它与any含义相同,表示类型不确定,可能是任意类型,但是它的使用有一些限制,不像any那样自由,可以视为严格版的any |
| never | 该类型为空,不包含任何值 |
| void | 一般用来对函数的返回值类型限制 |
| object | 小写object可以存所有非原始类型,Object可以存储包含object方法的类型(除了undefined和null) |
| tuple | 元祖,只读 |
| enum | 枚举,只读 |
| type | 类型声明 |
interface 与 type 的异同
interface命令与type命令作用类似,都可以表示对象类型。
很多对象类型既可以用 interface 表示,也可以用 type 表示。而且,两者往往可以换用,几乎所有的 interface 命令都可以改写为 type 命令。
它们的相似之处,首先表现在都能为对象类型起名。
type Country = {
name: string;
capital: string;
}
interface Country {
name: string;
capital: string;
}
上面示例是type命令和interface命令,分别定义同一个类型。
class命令也有类似作用,通过定义一个类,同时定义一个对象类型。但是,它会创造一个值,编译后依然存在。如果只是单纯想要一个类型,应该使用type或interface。
interface 与 type 的区别有下面几点。
(1)type能够表示非对象类型,而interface只能表示对象类型(包括数组、函数等)。
(2)interface可以继承其他类型,type不支持继承。
继承的主要作用是添加属性,type定义的对象类型如果想要添加属性,只能使用&运算符,重新定义一个类型。
type Animal = {
name: string
}
type Bear = Animal & {
honey: boolean
}
上面示例中,类型Bear在Animal的基础上添加了一个属性honey。
上例的&运算符,表示同时具备两个类型的特征,因此可以起到两个对象类型合并的作用。
作为比较,interface添加属性,采用的是继承的写法。
interface Animal {
name: string
}
interface Bear extends Animal {
honey: boolean
}
继承时,type 和 interface 是可以换用的。interface 可以继承 type。
type Foo = { x: number; };
interface Bar extends Foo {
y: number;
}
type 也可以继承 interface。
interface Foo {
x: number;
}
type Bar = Foo & { y: number; };
(3)同名interface会自动合并,同名type则会报错。也就是说,TypeScript 不允许使用type多次定义同一个类型。
type A = { foo:number }; // 报错
type A = { bar:number }; // 报错
上面示例中,type两次定义了类型A,导致两行都会报错。
作为比较,interface则会自动合并。
interface A { foo:number };
interface A { bar:number };
const obj:A = {
foo: 1,
bar: 1
};
上面示例中,interface把类型A的两个定义合并在一起。
这表明,interface 是开放的,可以添加属性,type 是封闭的,不能添加属性,只能定义新的 type。
(4)interface不能包含属性映射(mapping),type可以,详见《映射》一章。
interface Point {
x: number;
y: number;
}
// 正确
type PointCopy1 = {
[Key in keyof Point]: Point[Key];
};
// 报错
interface PointCopy2 {
[Key in keyof Point]: Point[Key];
};
(5)this关键字只能用于interface。
// 正确
interface Foo {
add(num:number): this;
};
// 报错
type Foo = {
add(num:number): this;
};
上面示例中,type 命令声明的方法add(),返回this就报错了。interface 命令没有这个问题。
下面是返回this的实际对象的例子。
class Calculator implements Foo {
result = 0;
add(num:number) {
this.result += num;
return this;
}
}
(6)type 可以扩展原始数据类型,interface 不行。
// 正确
type MyStr = string & {
type: 'new'
};
// 报错
interface MyStr extends string {
type: 'new'
}
上面示例中,type 可以扩展原始数据类型 string,interface 就不行。
(7)interface无法表达某些复杂类型(比如交叉类型和联合类型),但是type可以。
type A = { /* ... */ };
type B = { /* ... */ };
type AorB = A | B;
type AorBwithName = AorB & {
name: string
};
上面示例中,类型AorB是一个联合类型,AorBwithName则是为AorB添加一个属性。这两种运算,interface都没法表达。
综上所述,如果有复杂的类型运算,那么没有其他选择只能使用type;一般情况下,interface灵活性比较高,便于扩充类型或自动合并,建议优先使用。