我有两组字符串值,我希望将它们作为常量对象从一组映射到另一组。我想从该映射生成两种类型:一种用于键,一种用于值。
const KeyToVal = {
MyKey1: 'myValue1',
MyKey2: 'myValue2',
};
键很简单:
type Keys = keyof typeof KeyToVal;
我在获取值的编译时类型时遇到了麻烦。我想也许其中一种会起作用:
type Values = typeof KeyToVal[Keys];
type Values<K> = K extends Keys ? (typeof KeyToVal)[K] : never;
type Prefix<
K extends Keys = Keys,
U extends { [name: string]: K } = { [name: string]: K }
> = {[V in keyof U]: V}[K];
所有这些都使Values
成为string
。我还尝试将两个答案改编成How to infer typed mapValues using lookups in typescript?,但是要么我改错了答案,要么答案一开始就不适合我的情况。
答案 0 :(得分:3)
string
。
要使编译器推断文字类型,您必须通过具有适当设计的泛型类型参数的函数传递对象,这种情况似乎可以解决这种情况:
function t<V extends string, T extends {[key in string]: V}>(o: T): T {return o}
此功能的全部目的是捕获和保留类型以启用类型推断,否则它完全没有用,但是有了它,您就可以拥有
const KeyToVal = t({
MyKey1: 'myValue1',
MyKey2: 'myValue2',
});
type Keys = keyof typeof KeyToVal;
type Values = typeof KeyToVal[Keys]; // "myValue1" | "myValue2"
答案 1 :(得分:0)
您正在尝试从对象(可以具有任意数量的键/值)推断类型。您可以先描述类型(或者最好是一个接口),然后再像这样推断Kyes和Values:
type KeyToObjMap = {
some: "other",
more: "somemore",
};
type Keys = keyof KeyToObjMap;
type Values = KeyToObjMap[Keys];
let one: Values = "some";
let two: Values = "other";
let three: Keys = "some";
let four: Values = "somemore";
let five: Keys = "fun";
您将在IDE中正确显示突出显示。
答案 2 :(得分:0)
我知道它可能不相关,但是对于我的用例,我遇到了这个问题,因为我想基于对象或数组创建类型。所以我只是认为对于具有相同用例的人来说,使用此枚举可能会有用: 您可以像这样简单地定义一个枚举:
enum Arrow {
Up,
Down,
Left,
Right
}
您现在可以将此枚举用作类型:
type Props = {
arrow: Arrow
}
const Component = (props: Props) => {
switch(props.arrow) {
case Arrow.Up:
// go-up
case Arrow.Down:
// go-down
...
}
}
,您可以在组件中使用它:
<Component arrow={Arrow.top} />