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

dx_*_*_dt 7 typescript typescript-typings

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

const KeyToVal = {
    MyKey1: 'myValue1',
    MyKey2: 'myValue2',
};
Run Code Online (Sandbox Code Playgroud)

按键很简单:

type Keys = keyof typeof KeyToVal;
Run Code Online (Sandbox Code Playgroud)

我在获取值的编译时类型时遇到麻烦。我认为也许其中一种会起作用:

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];
Run Code Online (Sandbox Code Playgroud)

所有这些只是做的Valuesstring。我还尝试调整了两个答案,以适应如何使用打字稿中的查找来推断类型化的mapValues?,但要么我改写错误,要么答案根本不适合我的情况。

Ame*_*icA 72

实际上,您应该将其更改KeyToVal为以下声明:

const KeyToVal = {
    MyKey1: 'myValue1',
    MyKey2: 'myValue2',
} as const; // <----- add the <as const> here
Run Code Online (Sandbox Code Playgroud)

然后创建密钥类型:

type Keys = keyof typeof KeyToVal;
Run Code Online (Sandbox Code Playgroud)

现在您可以创建值的类型:

type ValuesTypes = typeof KeyToVal[Keys];
Run Code Online (Sandbox Code Playgroud)


art*_*tem 13

编译器会将字符串文字类型扩展为string,除非满足某些特定条件,如github issuePR中所述,或者将const断言用于文字值。Const断言出现在TypeScript 3.4中:

const KeyToVal = {
    MyKey1: 'myValue1',
    MyKey2: 'myValue2',
} as const;

type Keys = keyof typeof KeyToVal;
type Values = typeof KeyToVal[Keys]; //  "myValue1" | "myValue2"
Run Code Online (Sandbox Code Playgroud)

在3.4之前,有一种变通办法可以达到相同的效果。为了使编译器能够推断文字类型,您必须通过具有适当设计的泛型类型参数的函数传递对象,这种情况似乎可以解决这种情况:

function t<V extends string, T extends {[key in string]: V}>(o: T): T {return o}
Run Code Online (Sandbox Code Playgroud)

该功能的全部目的是捕获和保留类型以启用类型推断,否则它完全没有用,但是有了它,您可以拥有

const KeyToVal = t({
    MyKey1: 'myValue1',
    MyKey2: 'myValue2',
});

type Keys = keyof typeof KeyToVal;
type Values = typeof KeyToVal[Keys]; //  "myValue1" | "myValue2"
Run Code Online (Sandbox Code Playgroud)


小智 7

您正在尝试从对象(可以有任意数量的键/值)推断类型。您可以尝试先描述类型(或者更好的接口),然后像这样推断 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";
Run Code Online (Sandbox Code Playgroud)

您将在 IDE 中获得正确的突出显示。

集成开发环境

  • 这*几乎*有效。现在我需要运行时访问`KeyToObjMap`。 (2认同)

lee*_*len 6

不完全相同,但如果您有一个对象数组而不是单个对象,那么您可以通过执行以下操作提取已知属性的值来创建类型:

const keyToValArray = [
  { value: 'myValue1', label: 'myLabel1' },
  { value: 'myValue2', label: 'myLabel2' }
] as const;
type Keys = typeof keyToValArray[number]['value']; // 'myValue1' | 'myValue2'
Run Code Online (Sandbox Code Playgroud)