索引访问类型 - TypeScript 创建类型
索引访问类型
我们可以使用索引访问类型(indexed access type)查找另外一个类型上的特定属性:
type Person = { age: number; name: string; alive: boolean }; type Age = Person["age"]; // type Age = number type Name = Person["name"]; // type Name = string
因为索引名本身就是一个类型,所以我们也可以使用|
操作符、keyof
操作符或者其他类型:
type I1 = Person["age" | "name"]; // type I1 = string | number type I2 = Person[keyof Person]; // type I2 = string | number | boolean type AliveOrName = "alive" | "name"; type I3 = Person[AliveOrName]; // type I3 = string | boolean
如果你尝试查找一个不存在的属性,TypeScript 会报错:
type I1 = Person["alve"]; // Property 'alve' does not exist on type 'Person'.
接下来是对象数组示例:
const MyArray = [ { name: "Alice", age: 15 }, { name: "Bob", age: 23 }, { name: "Eve", age: 38 }, ]; console.log(MyArray); //数组 MyArray 的类型是: MyArray: { name: string; age: number; }[]
数组MyArray是有三个对象组成的。每个键是数字类型number
,每个值的类型是{name: string; age: number;}
。所以MyArray[number]
获得类型{name: string; age: number;}
,然后使用typeof
捕获其的字面量:
type Person = typeof MyArray[number]; /*type Person = { name: string; age: number; }*/ type Age = typeof MyArray[number]["age"]; //type Age = number type Age2 = Person["age"]; //type Age2 = number
作为索引的只能是类型,这意味着你不能使用const
创建一个变量引用:
const key = "age"; type Age = Person[key]; // Type 'key' cannot be used as an index type. // 'key' refers to a value, but is being used as a type here. Did you mean 'typeof key'?
然而你可以使用类型别名实现类似的重构:
type key = "age"; type Age = Person[key];
实例
假设有这样一个业务场景,一个页面要用在不同的 APP 里,比如淘宝、天猫、支付宝,根据所在 APP 的不同,调用的底层 API 会不同,我们可能会这样写:
const APP = ['TaoBao', 'Tmall', 'Alipay']; function getPhoto(app: string) { // ... } getPhoto('TaoBao'); // ok getPhoto('whatever'); // ok
如果我们仅仅是对 app 约束为string
类型,即使传入其他的字符串,也不会导致报错,我们可以使用字面量联合类型约束一下:
const APP = ['TaoBao', 'Tmall', 'Alipay']; type app = 'TaoBao' | 'Tmall' | 'Alipay'; function getPhoto(app: app) { // ... } getPhoto('TaoBao'); // ok getPhoto('whatever'); // not ok
但写两遍又有些冗余,我们怎么根据一个数组获取它的所有值的字符串联合类型呢?我们就可以结合上一篇的typeof
和本节的内容实现:
const APP = ['TaoBao', 'Tmall', 'Alipay'] as const; type app = typeof APP[number]; // type app = "TaoBao" | "Tmall" | "Alipay" function getPhoto(app: app) { // ... } getPhoto('TaoBao'); // ok getPhoto('whatever'); // not ok
asconst
将数组变为readonly
的元组类型。
鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com
图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!