基础
基础类型
-
boolean、number、string
- ts中最常见的数据类型
-
枚举 enum
- 表示一组常量值,形成了常量和值的一一映射
enum Color { Red = "#FF0000", Green = "#00FF00", Blue = "#0000FF" } function getColorName(color: Color): string { switch (color) { case Color.Red: return "红色"; case Color.Green: return "绿色"; case Color.Blue: return "蓝色"; } } console.log(getColorName(Color.Red)); // 输出:红色 -
any、unknown、void
- unknown类型的变量无法直接使用,经过类型判断or类型断言可以使用,对类型安全更友好
- void类型的变量只能赋值为null或undefined
-
never
- 表示不应该出现的值,抛出异常or死循环函数。
function error(message: string): never { throw new Error(message); } // 调用 error 函数,导致程序抛出异常 error("An error has occurred."); -
数组
- number[]
- 数组泛型
- 接口(不推荐)
- 类数组(只能用接口),常用的类数组都有官方的定义
IArguments,NodeList,HTMLCollection
-
元组 tuple
- 可用在函数的返回值为多种类型时
let tom: [string, number] = ['Tom', 25];
函数
支持可选参数、默认参数、剩余参数。
函数重载:函数名称相同,参数类型和数量不同,支持多种类型。
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string | void {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}
接口 interface
- 规定对象or函数类型
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
return source.search(subString) !== -1;
}
- 支持只读属性、可选属性、任意属性,普通属性不能多不能少,类型也要完全一致。
// 其他属性类型必须是任意属性的类型的子集
interface Person {
name: string;
age?: number;
[propName: string]: string | number;
}
类
-
增加public、private、protected修饰符
构造函数被private修饰,不允许继承和实例化 构造函数被protected修饰,不允许被实例化
-
抽象类
- 不能被实例化,只能被继承
- 基类,抽象方法必须被子类实现
abstract class Animal { public name; public constructor(name) { this.name = name; } public abstract sayHi(); } class Cat extends Animal { public eat() { console.log(`${this.name} is eating.`); } } let cat = new Cat('Tom'); // index.ts(9,7): error TS2515: Non-abstract class 'Cat' does not implement inherited abstract member 'sayHi' from class 'Animal'. -
interface、类和implements
- 将不同类之间的共有特性抽象成接口,一个接口可以被多个类implements,一个类也可以implements多个接口
💡 接口继承类 声明class A时,除了常见名字为A的类,还创建了名字为A的类型(实例的类型,不包含构造函数、静态属性、静态方法)。 因此接口可继承类,等同于继承接口。interface Alarm { alert(): void; } interface Light { lightOn(): void; lightOff(): void; } class Car implements Alarm, Light { alert() { console.log('Car alert'); } lightOn() { console.log('Car light on'); } lightOff() { console.log('Car light off'); } }
进阶
高级类型
-
联合类型 |
-
交叉类型 &
-
类型断言
// 非空断言 let myString: string | undefined = "Hello World"; let strLength: number = myString!.length; // 非空断言,告诉编译器 myString 不为空 // 赋值断言 let myNumber: any = "123"; // myNumber 的类型为 any let numLength: number = (myNumber as string).length; // 赋值断言,将 myNumber 类型转换为 string -
类型别名
-
相同点
都可以定义对象or函数
都允许继承
-
不同点
定义对象 vs 定义别名
type可定义基本类型,interface不行
interface可合并重复声明,type不行
-
涉及到联和和交叉用type,涉及到类用interface,其他情况好像都可以
// 字符串字面量类型
type EventNames = 'click' | 'scroll' | 'mousemove';
泛型
使用场景:
定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
官方定义(设计哲学):API需要考虑可重用性,组件不仅能支持当前的数据类型,还要能支持未来的数据类型。C#和Java都可以使用泛型。
使用方法:
function createArray<T>(length: number, value: T): Array<T> {
let result: T[] = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
// 自动推算类型
createArray(3, 'x'); // ['x', 'x', 'x']
// 也可以手动指定
createArray<string>(3, 'x'); // ['x', 'x', 'x']
泛型的作用是临时占位
-
泛型约束
函数内使用泛型变量时,不知道它是什么类型,使用属性or方法编译会报错。
可以定义一个接口,里面包含我们需要使用的属性or方法。然后让泛型extends这个接口。
同时,如果调用函数时,传入的参数没有这些属性or方法,编译会报错。
interface Lengthwise { length: number; } function loggingIdentity<T extends Lengthwise>(arg: T): T { console.log(arg.length); return arg; } loggingIdentity(7); // index.ts(10,17): error TS2345: Argument of type '7' is not assignable to parameter of type 'Lengthwise'.泛型 也可以 extends泛型。
function copyFields<T extends U, U>(target: T, source: U): T { for (let id in source) { target[id] = (<T>source)[id]; } return target; } let x = { a: 1, b: 2, c: 3, d: 4 }; copyFields(x, { b: 10, d: 20 }); -
泛型类
class GenericNumber<T> { zeroValue: T; add: (x: T, y: T) => T; } let myGenericNumber = new GenericNumber<number>(); myGenericNumber.zeroValue = 0; myGenericNumber.add = function(x, y) { return x + y; }; -
泛型默认类型
ts 2.3后
当没有指定泛型类型,且无法推断时,使用默认类型。
function createArray**<T = string>**(length: number, value: T): Array<T> { let result: T[] = []; for (let i = 0; i < length; i++) { result[i] = value; } return result; }
操作符
typeof、keyof
type Keys = "a" | "b"
// in:遍历枚举类型
type Obj = {
[p in Keys]: any
} // -> {a:any, b:any}
// T[K]
let type1: Obj["a"] //any
// extends:泛型约束
常用工具类型
Partial
Required
Readonly
Pick
Record
等。。。
Partial:先遍历T的key,通过索引获取类型,通过可选操作符重新定义为可选的
实战
声明文件
实战场景一:约束后端接口类型
参考
ts playground: ts编译js