You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中如何用字符串访问只读对象并指定返回类型?

TypeScript字符串索引对象属性的类型问题

问题1:简单对象字符串索引的类型处理

在TypeScript中用字符串访问对象属性时遇到类型错误:

const parent2 = {child: 'name'}
const index2: string = 'child';
const child3 = parent2[index2]

报错信息:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ child: string; }'.
No index signature with a parameter of type 'string' was found on type '{ child: string; }'

需要简便方法让parent2[index2]返回'name' | undefined类型。

问题2:嵌套只读对象的字符串索引访问

处理嵌套只读对象时手动构造allowStringIndex类型来支持字符串索引并保留自动补全,但过程十分繁琐,想找简便方法实现nestedObject[grandParentIndex]?.[parentIndex]这样的访问:

const nestedObject = {grandParent: {name: 'grandparent', parent: {name: 'parent', child: {name: 'child'}}}} as const;
type child = {name: 'child', [key: string]: 'child' | undefined}
type parent = {name: 'parent', child: child}
type overrideParent = parent & {[key: string]: parent[keyof parent] | undefined}
type grandParent = {name: 'grandparent', parent: overrideParent}
type overrideGrandParent= grandParent & {[key: string]: grandParent[keyof grandParent] | undefined}

type allowStringIndex = {grandParent: overrideGrandParent} & {[key: string]: overrideGrandParent | undefined}

const castedObject = nestedObject as allowStringIndex;
const grandParentIndex: string = 'grandparent';
const parentIndex: string = 'parent'

const child = nestedObject[grandParentIndex]?.[parentIndex]?.['child']
const parent1 = castedObject[grandParentIndex]?.[parentIndex]

尝试过递归类型,但效果不理想。


解决方案

针对问题1:简单对象的类型适配

定义通用工具类型,给原对象类型添加字符串索引签名,同时保留原有属性的精确类型:

type AllowStringIndex<T> = T & { [key: string]: T[keyof T] | undefined };

const parent2 = {child: 'name'}
const index2: string = 'child';
// 类型断言为适配后的类型
const child3 = (parent2 as AllowStringIndex<typeof parent2>)[index2];
// child3的类型为 'name' | undefined

如果不需要自动补全,也可以直接在定义对象时添加索引签名,但会丢失属性补全能力:

const parent2: { child: string; [key: string]: string | undefined } = {child: 'name'}
const index2: string = 'child';
const child3 = parent2[index2]; // 类型为 string | undefined

针对问题2:嵌套只读对象的递归类型适配

编写递归通用工具类型,自动给嵌套对象的每一层添加字符串索引签名:

type RecursiveAllowStringIndex<T> = 
  T extends Record<string, unknown> 
    ? T & { [key: string]: RecursiveAllowStringIndex<T[keyof T]> | undefined }
    : T;

const nestedObject = {grandParent: {name: 'grandparent', parent: {name: 'parent', child: {name: 'child'}}}} as const;
// 转换类型
const castedObject = nestedObject as RecursiveAllowStringIndex<typeof nestedObject>;

const grandParentIndex: string = 'grandparent';
const parentIndex: string = 'parent';

const parent1 = castedObject[grandParentIndex]?.[parentIndex];
// parent1的类型为 { readonly name: "parent"; readonly child: { readonly name: "child"; }; } | undefined
const child = castedObject[grandParentIndex]?.[parentIndex]?.['child'];
// child的类型为 { readonly name: "child"; } | undefined

该递归类型会自动遍历对象每一层,给每个对象类型添加字符串索引签名,同时保留原有属性的只读特性和精确类型,也支持自动补全。


内容的提问来源于stack exchange,提问作者Clifford B. Wolfe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 03:10:36