typescript索引访问类型用[key]语法静态提取嵌套属性类型,需每层为确定类型;支持多层连续索引、可选属性需确保存在、联合类型产生交集、配合keyof和泛型可动态复用,但不可索引不存在属性或裸泛型。

在 TypeScript 中,索引访问类型(Indexed Access Types)用 [key] 语法从类型中提取属性的类型,包括嵌套接口中的子属性。关键在于:路径必须是静态、可推导的,且每层都得是确定的类型(不能是联合类型或 any)。
基础用法:一层嵌套
如果有一个接口包含另一个接口类型的字段,可以直接用点号链式写法(但注意:不是真的用点号,而是逐层索引):
interface User {
profile: {
name: string;
age: number;
};
}
type NameType = User['profile']['name']; // string
type AgeType = User['profile']['age']; // number
这里 User['profile'] 先得到内层对象类型,再对其做 ['name'] 索引,就拿到了最终类型。
多层嵌套:支持任意深度
只要每一级都是具体对象类型(非联合、非泛型未约束),就可以连续索引:
对设计或页面进行 WCAG 2.1 AA 无障碍审计。触发关键词:“audit accessibility”、 “check a11y”、 “is this accessible?” 或在审查设计时使用。
interface ApiResponse {
data: {
user: {
settings: {
theme: 'light' | 'dark';
notifications: boolean;
};
};
};
}
type ThemeType = ApiResponse['data']['user']['settings']['theme']; // 'light' | 'dark'
type NotifType = ApiResponse['data']['user']['settings']['notifications']; // boolean
- 每一对方括号只取一个层级,不能写成
ApiResponse['data.user.settings.theme'] - 如果某一层是可选属性(
settings?: { ... }),需先确保它存在,否则会报错或得到never - 若字段是联合类型(如
user: User | null),则['user']会得到联合类型,后续索引可能受限
配合 keyof 和泛型动态提取
当需要根据键名动态获取嵌套类型时,可以结合 keyof 和泛型提升复用性:
type NestedValue<t k1 extends keyof t k2> = T[K1][K2]; type SettingsTheme = NestedValue<apiresponse>['settings']['theme']; </apiresponse></t>
更通用的写法(支持三层):
type DeepProp<t k1 extends keyof t k2 k3> = T[K1][K2][K3]; type Theme = DeepProp<apiresponse>['theme']; </apiresponse></t>
- 这种泛型定义让类型提取可复用,适合工具类型封装
- 编译器会检查每个 key 是否真实存在于对应层级,提供类型安全
- 不推荐过度泛化——四层以上嵌套建议拆解或重构接口结构
注意事项和常见陷阱
索引访问看似简单,但容易踩坑:
-
不能索引不存在的属性:比如
User['missing']会报错;可用可选链U['profile']?['name']但仅限值层面,类型层面不适用 -
联合类型会导致交叉结果:若
profile: ProfileA | ProfileB,则User['profile']['name']是ProfileA['name'] & ProfileB['name'](交集),而非并集 -
映射类型或泛型未实例化时无法索引:例如
T['x']中T是裸泛型参数,除非约束为对象类型,否则会报错 -
数组元素类型要加 number:如
users: User[],取元素类型是UserList['users'][number],不是['users'][0]










