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

TypeScript中使用Interface定义对象时如何获取其实际键?

问题解答

当你用IAddress接口直接标注对象变量时,无法直接获取对象的实际键名类型,原因是:

  • IAddress定义了[key: string]: IPerson的索引签名,TypeScript会将变量的类型收窄为IAddress,此时typeof personInAddressObj的类型就是IAddress,而keyof IAddress的结果是string,自然无法得到具体的"someAddress1" | "someAddress2"。
  • 去掉接口标注后,TypeScript会自动推断对象的字面量类型,保留所有具体键名,因此keyof能拿到期望的联合类型。

解决方案:兼顾类型约束与具体键名保留

如果你既要让对象符合IAddress的类型规则,又要保留实际键名的类型信息,可以用以下两种方式:

1. 先推断对象类型,再验证约束

先创建带as const的对象让TypeScript推断具体类型,再通过类型检查确保它符合IAddress的要求:

interface IPerson {
    name: string;
}
interface IAddress {
    [key: string]: IPerson;
}

// 先创建对象,保留具体键名类型
const personInAddressObj = {
    someAddress1: {
        name: 'John',
    },
    someAddress2: {
        name: 'Jacob',
    }
} as const;

// 验证对象是否符合IAddress类型,不符合会触发编译错误
type _VerifyAddress = typeof personInAddressObj extends IAddress ? true : false;

type Keys = keyof typeof personInAddressObj; // "someAddress1" | "someAddress2"

2. 使用泛型函数约束类型

通过泛型函数接收对象,既约束对象符合IAddress,又返回对象的具体字面量类型:

interface IPerson {
    name: string;
}
interface IAddress {
    [key: string]: IPerson;
}

function createAddress<T extends IAddress>(address: T): T {
    return address;
}

const personInAddressObj = createAddress({
    someAddress1: {
        name: 'John',
    },
    someAddress2: {
        name: 'Jacob',
    }
} as const);

type Keys = keyof typeof personInAddressObj; // "someAddress1" | "someAddress2"

这两种方式都能在确保对象类型合法的前提下,保留实际键名的类型信息,满足你的需求。

内容的提问来源于stack exchange,提问作者Kustemit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 11:31:02