记录typescript中有一些很难理解的东西。
1. keyof: 接受一个对象,返回该对象的所有属性的联合类型
interface Part {
id: number;
name: string;
subparts: Part[];
updatePart(newName: string): void;
}
type A = keyof Part
2. typeof 获取变量的类型
only legal to use
typeofon identifiers (i.e. variable names) or their properties.
// typeof 'helloworld' // Identifier expected.
const a = 'hello typescript'
// typeof a
3. extends 条件类型
extends比较好理解的是 是否可分配,可以理解成继承关系。但是当extends与union一起使用时,会有distribute操作。
// typescipt中有一个Exclude<T, U>工具方法,这里Extends可以通过
type MyExclude<T, U> = T extends U ? never : T
type AB = MyExclude<'a' | 'b' |'c', 'a'> // 'a' | 'b'
// 'a' | 'b' | 'c' extends 'a'
// 相当于
// 'a' extends 'a' | 'b' extends 'a' | 'c' extends 'a'
4.条件类型中的infer
// 最常用的例子
// 获取函数返回值的类型
type ReturnType<T extends Function> = T extends (...args: any[]) => infer R ? R : never;
type R = ReturnType<(a: number) => number> // number
5. Array value的联合类型
通过keyof可以获取对象的联合类型
interface Game {
name: string
style: string
}
type AU = keyof Game // 是 'name' | 'style'的 union type
如果将keyof用到数组上,获取到的是length, toString这些原型上的属性。
type ValueOf<T extends any[]> = T[number]
// 这里用 number 的index accessable 就可以获取数组的值的联合类型
type VARR = ValueOf<[1, 'helloworld', true]> // 1 | 'helloworld' | true
这里有个issue,可以看下 keyof for array
6. 方法的重载overload
如何实现函数方法重载呢?
// 某个实现的setter或者getter经常会有类似的实现
abstract class A {
abstract test(name: string): string
abstract test(name: string, value: string): void
}
class RealA implements A {
test(name: string): string
test(name: string, value: string): void
test(name: string, value?: string): string | void {
if (value) {
// someObject[name] = value
} else {
return someObject[name]
}
}
}
7. class类型
class A {}
// 类定义了两个类型:
// 实例类型 Person
// 构造函数类型 typeof Person
function create(ctor: { new(): A }): A {
return new ctor();
}
// 与下面的相同
// function create(ctor: typeof A): A {
// return new ctor();
// }
let a = create(A); // a is instanceof A