TypeScript从对象的对象创建ID类型[重复]

v8wbuo2f  于 2023-01-21  发布在  TypeScript
关注(0)|答案(2)|浏览(141)

此问题在此处已有答案

new Typescript "satisfies" operator(1个答案)
昨天关门了。
假设我们有这样的 typescript 代码

interface Animal {
    name: string
}
const animals: {[key: string]: Animal} = {
    bear: { name: "Bear" },
    lion: { name: "Lion" },
};
type AnimalId = keyof typeof animals;

在本例中,AnimalId的类型为string | number
我希望它具有以下类型:"bear" | "lion"
我也试过这个:

interface Animal {
    name: string
}
const animals = {
    bear: { name: "Bear" },
    lion: { name: "Lion" },
};
type AnimalId = keyof typeof animals;

在本例中,AnimalId确实具有正确的类型"bear" | "lion",但是没有对animals对象进行类型检查
我也接受animals是数组或Map的解决方案,在这种情况下我使用对象,因为由于存在keyof关键字,这似乎是最简单的方法。
我不想手动将AnimalId定义为"bear" | "lion",因为在真实的的程序中会有更多的id需要跟踪,而且必须在多个地方更改它们是非常不方便的。

hxzsmxv2

hxzsmxv21#

最好的选择是在typoescript 4.9及更高版本中使用新的satasifes运算符:

const animals = {
    bear: { name: "Bear" },
    lion: { name: "Lion", tes: 0 }, // Error
} satisfies Record<string, Animal>;

Playground链接
如果你使用的是旧版本,你也可以使用id函数来进行推理:

const animals = makeAniumlas({
    bear: { name: "Bear" },
    lion: { name: "Lion", tes: 0 }, // Error
})

type AnimalId = keyof typeof animals;

function makeAniumlas<K extends PropertyKey>(o: Record<K, Animal>) {
    return o;
}

Playground链接

zz2j4svz

zz2j4svz2#

新的satisfies运算符正是为此目的而生成的。

interface Animal {
    name: string
}
const animals = {
    bear: { name: "Bear" },
    lion: { name: "Lion" },
    dog: {} // error: Property 'name' is missing
} satisfies {[key: string]: Animal};

type AnimalId = keyof typeof animals; // "bear" | "lion" | "dog"

Playground

相关问题