问题描述
我有两组字符串值,我想将它们作为常量对象从一组映射到另一组.我想从该映射生成两种类型:一种用于键,一种用于值.
I have two sets of string values that I want to map from one to the other as a constant object. I want to generate two types from that mapping: one for keys and one for values.
const KeyToVal = {
MyKey1: 'myValue1',
MyKey2: 'myValue2',
};
按键很简单:
type Keys = keyof typeof KeyToVal;
我在获取编译时类型的值时遇到问题.我想也许其中之一会奏效:
I'm having trouble getting a compile-time type for the values. I thought maybe one of these would work:
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在打字稿中查找?,但要么我的改编有误,要么答案一开始就不适合我的场景.
All of these just made Values
to be string
. I also tried adapting the two answers to How to infer typed mapValues using lookups in typescript?, but either I got my adaptations wrong, or the answers didn't fit my scenario in the first place.
推荐答案
编译器会将字符串字面量类型扩展为 string
,除非满足某些特定条件,如 github 问题 和 PR 或 const assertion 用于文字值.Const 断言出现在 TypeScript 3.4 中:
The compiler will widen string literal type to string
, unless some specific conditions are met as explained in github issues and PR, or const assertion is used for literal value. Const assertions appeared in TypeScript 3.4:
const KeyToVal = {
MyKey1: 'myValue1',
MyKey2: 'myValue2',
} as const;
type Keys = keyof typeof KeyToVal;
type Values = typeof KeyToVal[Keys]; // "myValue1" | "myValue2"
在 3.4 之前,有一种变通方法可以达到相同的效果.为了让编译器推断文字类型,您必须通过一个具有适当制作的泛型类型参数的函数来传递您的对象,这个似乎可以解决这种情况:
Prior to 3.4, there was a workaround to get the same effect. To make the compiler infer literal types, you had to pass your object through a function with appropriately crafted generic type parameters, this one seems to do the trick for this case:
function t<V extends string, T extends {[key in string]: V}>(o: T): T {return o}
这个函数的全部目的是捕获和保留类型以启用类型推断,否则它完全没用,但有了它你就可以了
The whole purpose of this function is to capture and preserve types to enable type inference, it's entirely useless otherwise, but with it you can have
const KeyToVal = t({
MyKey1: 'myValue1',
MyKey2: 'myValue2',
});
type Keys = keyof typeof KeyToVal;
type Values = typeof KeyToVal[Keys]; // "myValue1" | "myValue2"
这篇关于Typescript 中对象的键和值的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!