以下总结可能会基于泛型操作,需提前了解泛型
一、keyof类型操作
keyof作用于一个A类型,并生成一个新的B类型,这个B类型的取值是A类型中所有属性名称所构成的联合类型。
-
正常示例:
type TypeA = { a:string, b:number, c:boolean } type TypeB = TypeA // 'a' | 'b' | 'c' -
索引类型(string):
type TypeA = { [index:string]:string } type TypeB = keyof TypeA // string | number当作用类型是索引类型,且属性名类型是string时,新类型是string | number的联合类型。因为即使是number类型的属性名,最终也会转换成string类型。参考以下:
type TypeA = { [index:string]:string } let a:TypeA = { name:'name', 1:'数字' } -
索引类型(number):
type TypeA = { [index:number]:string } type TypeB = keyof TypeA // number当属性名类型是number时,则新类型只能是number。
二、typeof类型操作
在jvascript中,typeof操作符用于确定一个基础类型。但在typescript中,针对这个操作符做出了一些增强,可以返回变量或属性的类型。这个操作符针对基础类型,并没有太多的作用,但结合其他的类型操作符,可以方便的表达很多类型。
-
示例:
function f() { return { x: 10, y: 3 }; } type P = ReturnType<typeof f>; // 通过typeof获取一个方法的类型,在推断获取其返回类型 // type P = { // x: number; // y: number; // } type Union = P & { z:number } // type P = { // x: number; // y: number; // z: number // }值得注意的是,在javascript中,使用typeof操作符用于一个方法或者对象,只会返回基础类型object或者function,但在typescript中,会去获取其具体类型定义。
-
限制
在typescript中,typeof的操作特意的被限制了部分行为。理论上来将,typeof可以用于任意合法的表达式,以下2个操作在理论上相等:
function msgbox(){ return { a:1 } } type A = ReturnType<typeof msgbox> //操作A type B = typeof msgbox("Are you sure you want to continue?"); //操作B但为了避免困惑,在typescript中,typeof只有被用于变量或者其属性,才被认为是合法行为,因此上述操作B会提示错误。这个是官网的表达,但也存在直接作用域字符串的情形与此表达相悖。
三、通过索引获取类型
索引一词,一般用于数组元素中,如根据下标索引,获取对应的元素。从概念上讲,只要能根据一个值A,能快速定位到另外一个值B,都可以说这个值A是值B的索引。下述示例中,需要注意一个概念,这是在typescript的类型系统中,所有的操作都是基于类型的。
-
普通对象
type Person = { age: number; name: string; alive: boolean }; type Age = Person["age"];如声明了一个类型Person,可以直接根据其属性作为键值,获取对应的属性值的类型。此时age并不是作为一个值,而是一个字面量类型。
-
数组
type Person = { age: number; name: string; alive: boolean }; type PersonArr = Array<Person> // type Example = PersonArr[0] type Example = PersonArr[number]在针对数组类型中,可以直接使用类型number获取元素类型,此时也可以传入具体的下标索引。因为是在操作类型,这些索引最终都会被转化为number类型。
-
索引对象
在普通对象中,可以直接使用属性名,快捷的获取类型,但在索引对象中,并不知道所有的类型。如下:
type O = { [index:number]:boolean, do:number } type N = O["do"] // number type B = O[number] // boolean针对属性名称do,可以获取到类型number,这点和普通对象一致。但针对索引相关的属性,只需要提供一个number类型,便可以获取到对应的boolan类型,和数组类型一致。