来自Typescript中对象的键和值的类型

时间:2018-12-07 01:56:18

标签: typescript typescript-typings

我有两组字符串值,我希望将它们作为常量对象从一组映射到另一组。我想从该映射生成两种类型:一种用于键,一种用于值。

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?,但是要么我改错了答案,要么答案一开始就不适合我的情况。

3 个答案:

答案 0 :(得分:3)

除非满足github issuesPR

中所述的某些特定条件,否则编译器会将字符串文字类型扩展为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中正确显示突出显示。

IDE

答案 2 :(得分:0)

我知道它可能不相关,但是对于我的用例,我遇到了这个问题,因为我想基于对象或数组创建类型。所以我只是认为对于具有相同用例的人来说,使用此枚举可能会有用: 您可以像这样简单地定义一个枚举:

enum Arrow {
  Up,
  Down,
  Left,
  Right
}

您可以详细了解herehere

您现在可以将此枚举用作类型:

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} />