介绍
基本类型
1.八种内置类型
2.any nuknown onject Object void never
用法
变量类型标注(除数组)
let a: number = 2;
变量类型标注(数组)
数字类型数组
let arr: number[] = [1, 2, 3, 4]; //数字类型的数组
数字类型数组
let arr1: Array<number> = [1, 2, 3, 4, 5];
定义数组每一个位置的类型的数组(也叫元组)
let arr: [string, number] = ["小满", 22]; //这样的方式就叫做元组,定义了每个位置需要满足的不同类型
嵌套写法
let arr1: Array<number> = [1, 2, 3, 4, 5];
let arr2: Array<string> = ["1,2,3,4,5"];
let arr3: Array<boolean> = [true];
//泛型数组套娃写法(还能够决定数组里面数组的类型之类的)
let arr4: Array<Array<number>> = [[123], [456]];
函数类型标注
function test(a: number, b: number): void {}
const fn = (name: string, age: number): string => {
return name + age;
};
interface 与 type
这两个 ts 的语法就像是函数一样,一次生成多次调用,因为要描述的类型往往可能是一个复杂对象,或者是一个函数,那么用这两种方式定义好类型之后,就可以在后面随便引用而不用每次遇到就写一遍
定义函数
type Condition = (n: number) => boolean;
interface Condition {
(n: number): boolean;
}
function sum(numbers: number[], callBack: Condition) {
let s = 0;
numbers.forEach((n) => {
if (callBack(n)) {
s += n;
}
});
return s;
}
定义对象
interface User {
name: string;
age: number;
}
type User = {
name: string;
age: number;
};
const fn = (user: User): User => {
//这里的参数填写方式就变得简单了
return user;
};
联合类型与交叉类型
凡是进行 ts 标注的地方都是可以使用& 和 | 的语法来表示
let myPhone: number | string = "010-820";
interface Pople {
name: string;
age: number;
}
interface Man {
sex: number;
}
const xiaoman = (man: Pople & Man): void => {
console.log(man);
};
类型断言
对类型采用 as 的语法来明确变量的类型
let fn = function (num: number | string): void {
console.log((num as string).length); //用括号括起来,as断言他是string类型
};
let fn = (type: A | B) => {
console.log((<A>type).run);
};
枚举(参与运行)
枚举其实是 js 真正要运行的内容,可以认为就是一个变量
enum Color {
no = "NO",
yes = 1,
}
//可以认为这就是一个变量
console.log(Color.no);
泛型
泛型函数
function Sub<T, U>(a: T, b: U): Array<T | U> {
//这个T跟U随便起名字都行,没有强制规范
const params: Array<T | U> = [a, b];
return params;
}
Sub<Boolean, number>(false, 1); //我们这里就将其定义为布尔值类型跟数字类型
interface + 泛型
interface MyInter<T> {
(arg: T): T;
}
function fn<T>(arg: T): T {
return arg;
}
let result: MyInter<number> = fn;
泛型定义类
class Sub<T> {
attr: T[] = []; //这里的:只是普通的:
add(a: T): T[] {
return [a];
}
}
类型演算
根据已知的信息,计算出新的类型
typeof
typeof 是用在实际的对象上,函数上,获取他的类型
interface Person {
name: string;
age: number;
}
const sem: Person = { name: "semlinker", age: 30 };
type Sem = typeof sem; // type Sem = Person
keyof
同理,获取 key 值
in
进一步约束属性名只能是 name 或者 age,采用 in 关键字
type Obj = {
[p in "name" | "age"]: string;
};
infer
占位符
假设你想从一个函数类型中推断出它的参数类型。可以使用 <font style="color:rgba(0, 0, 0, 0.85);">infer</font>
type FunctionArgs<T> = T extends (arg: infer U) => any ? U : never;
// 示例函数
function add(a: number, b: number) {
return a + b;
}
// 推断add函数的参数类型
type AddArgs = FunctionArgs<typeof add>;
// AddArgs的类型为number[],因为add函数有两个参数,所以推断出参数类型的数组
在这个例子中,<font style="color:rgba(0, 0, 0, 0.85);">FunctionArgs</font>
是一个条件类型,它的定义是:如果 <font style="color:rgba(0, 0, 0, 0.85);">T</font>
(这里 <font style="color:rgba(0, 0, 0, 0.85);">T</font>
代表一个函数类型)扩展自一个函数,这个函数接受一个参数 <font style="color:rgba(0, 0, 0, 0.85);">arg</font>
,并且参数类型是通过 <font style="color:rgba(0, 0, 0, 0.85);">infer</font>
占位符 <font style="color:rgba(0, 0, 0, 0.85);">U</font>
来表示的,那么就返回 <font style="color:rgba(0, 0, 0, 0.85);">U</font>
;否则返回 <font style="color:rgba(0, 0, 0, 0.85);">never</font>
。通过将 <font style="color:rgba(0, 0, 0, 0.85);">typeof add</font>
代入 <font style="color:rgba(0, 0, 0, 0.85);">T</font>
,就可以推断出 <font style="color:rgba(0, 0, 0, 0.85);">add</font>
函数的参数类型数组。
extend
继承(约束)
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
特殊用法
构造函数约束
class User{ loginid:string, loginpwd:string, } function createUser(cls:new() =>
User) :User{ return new cls(); }