Appearance
关键字
keyof
keyof 与 Object.keys 相似 不过 keyof 是用来获取对象类型的键的
typescript
interface Person {
age: number;
name: string;
}
type Player = {
age: number;
name: string;
};
type PersonKeys = keyof Person; // --> "age" | "name"
type PlayerKey = keyof Player; // --> "age" | "name"
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
typeof
typeof 用来返回一个值的 type
typescript
const s = 'hello';
const n: typeof s; // --> const n: string
1
2
2
例如 当我们想把多个工具合成一个的时候 就可以用 typeof 帮我们减少重复定义
typescript
import logger from './logger';
import utils from './utils';
interface Context extends KoaContext {
logger: typeof logger;
utils: typeof utils;
}
1
2
3
4
5
6
7
2
3
4
5
6
7
extends
extends 用来继承
注意 只有 interface 和 class 才可以继承
type 关键字声明的类型别名无法继承
typescript
interface Person {
name: string;
age: number;
}
interface Player extends Person {
item: 'ball' | 'swing';
}
const p1: Player = {
name: 'nanshu',
age: 18,
item: 'ball',
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
in
in 关键字可以帮助我们生成映射类型
typescript
enum Letter {
A = 'a',
B = 'b',
C = 'c',
}
type LetterMap = {
[key in Letter]: string;
};
// 等价于
type _LetterMap = {
a: string;
b: string;
c: string;
};
type Keys = 'name' | 'sex';
type PersonMap = {
[key in Keys]: string;
};
// 等价于
type _PersonMap = {
name: string;
sex: string;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
is
is 用作类型保护
typescript
function isString1(test: any): test is string {
return typeof test === 'string';
}
function isString2(test: any): boolean {
return typeof test === 'string';
}
const a = isString1('string'); // --> true
const b = isString2('string'); // --> true
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
这样来看 似乎两者没有差别 都能正确判断 string 类型 但是如果场景复杂一点 如下
typescript
function doSomething(params: any) {
if (isString1(params)) {
params.toLowerCase();
// params.xxx(); // --> Property 'xxx' does not exist on type 'string'
}
if (isString2(params)) {
params.xxx();
}
}
doSomething('string'); // TypeError: params.xxx is not a function
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
isString1 判断后的结果会返回一个 string 的保护类型 而 isString2 因为 params 是 any 会绕过 ts 的检查 所以就算调用了一个 string 类型上不存在的属性 也不会在编码阶段有任何问题 只有在运行时候才会报错
infer
infer 可以帮助我们推断出函数的返回值
typescript
type a<T> = T extends (...args: any) => infer R ? R : any;
type b = a<() => string>; // type b = string
1
2
3
2
3