gpt4 book ai didi

typescript - 如何使 Typescript 推断对象的键但定义其值的类型?

转载 作者:搜寻专家 更新时间:2023-10-30 20:37:49 26 4
gpt4 key购买 nike

我想定义一个对象的类型,但让 typescript 推断键并且没有那么多的开销来创建和维护所有键的 UnionType。

键入一个对象将允许所有字符串作为键:

const elementsTyped: { 
[key: string]: { nodes: number, symmetric?: boolean }
} = {
square: { nodes: 4, symmetric: true },
triangle: { nodes: 3 }
}

function isSymmetric(elementType: keyof typeof elementsTyped): boolean {
return elementsTyped[elementType].symmetric;
}
isSymmetric('asdf'); // works but shouldn't

推断整个对象将显示错误并允许所有类型的值:

const elementsInferred = {
square: { nodes: 4, symmetric: true },
triangle: { nodes: 3 },
line: { nodes: 2, notSymmetric: false /* don't want that to be possible */ }
}

function isSymmetric(elementType: keyof typeof elementsInferred): boolean {
return elementsInferred[elementType].symmetric;
// Property 'symmetric' does not exist on type '{ nodes: number; }'.
}

我得到的最接近的是这个,但它不想维护这样的键集:

type ElementTypes = 'square' | 'triangle'; // don't want to maintain that :(
const elementsTyped: {
[key in ElementTypes]: { nodes: number, symmetric?: boolean }
} = {
square: { nodes: 4, symmetric: true },
triangle: { nodes: 3 },
lines: { nodes: 2, notSymmetric: false } // 'lines' does not exist in type ...
// if I add lines to the ElementTypes as expected => 'notSymmetric' does not exist in type { nodes: number, symmetric?: boolean }
}

function isSymmetric(elementType: keyof typeof elementsTyped): boolean {
return elementsTyped[elementType].symmetric;
}
isSymmetric('asdf'); // Error: Argument of type '"asdf"' is not assignable to parameter of type '"square" | "triangle"'.

有没有更好的方法来定义对象而不维护键集?

最佳答案

所以你想要一些可以推断键但限制值类型并使用 excess property checking 的东西禁止额外的属性。我认为获得这种行为的最简单方法是引入辅助函数:

// Let's give a name to this type
interface ElementType {
nodes: number,
symmetric?: boolean
}

// helper function which infers keys and restricts values to ElementType
const asElementTypes = <T>(et: { [K in keyof T]: ElementType }) => et;

这个辅助函数 infers et 的映射类型中的类型 T。现在你可以像这样使用它:

const elementsTyped = asElementTypes({
square: { nodes: 4, symmetric: true },
triangle: { nodes: 3 },
line: { nodes: 2, notSymmetric: false /* error where you want it */}
});

生成的 elementsTyped 的类型(一旦您修复了错误)将具有推断键 squaretriangleline ,值为 ElementType

希望对你有用。祝你好运!

关于typescript - 如何使 Typescript 推断对象的键但定义其值的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54598322/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com