TypeScript 中是否有类似于“keyof"的“valueof"? [英] Is there a `valueof` similar to `keyof` in TypeScript?
问题描述
我希望能够将一个对象属性分配给一个给定键和值作为输入的值,但仍然能够确定值的类型.解释起来有点困难,所以这段代码应该可以揭示问题:
I want to be able to assign an object property to a value given a key and value as inputs yet still be able to determine the type of the value. It's a bit hard to explain so this code should reveal the problem:
type JWT = { id: string, token: string, expire: Date };
const obj: JWT = { id: 'abc123', token: 'tk01', expire: new Date(2018, 2, 14) };
function print(key: keyof JWT) {
switch (key) {
case 'id':
case 'token':
console.log(obj[key].toUpperCase());
break;
case 'expire':
console.log(obj[key].toISOString());
break;
}
}
function onChange(key: keyof JWT, value: any) {
switch (key) {
case 'id':
case 'token':
obj[key] = value + ' (assigned)';
break;
case 'expire':
obj[key] = value;
break;
}
}
print('id');
print('expire');
onChange('id', 'def456');
onChange('expire', new Date(2018, 3, 14));
print('id');
print('expire');
onChange('expire', 1337); // should fail here at compile time
print('expire'); // actually fails here at run time
我尝试将 value: any
更改为 value: valueof JWT
但这没有用.
I tried changing value: any
to value: valueof JWT
but that didn't work.
理想情况下,onChange('expire', 1337)
会失败,因为 1337
不是日期类型.
Ideally, onChange('expire', 1337)
would fail because 1337
is not a Date type.
如何将 value: any
更改为给定键的值?
How can I change value: any
to be the value of the given key?
推荐答案
UPDATE:看起来问题标题吸引了人们寻找所有可能的属性值类型的联合,类似于 keyof
给出的方式您是所有可能的属性键类型的联合.让我们先帮助那些人.您可以使用 索引访问类型,以 keyof T
作为键,如下所示:
UPDATE: Looks like the question title attracts people looking for a union of all possible property value types, analogous to the way keyof
gives you the union of all possible property key types. Let's help those people first. You can make a ValueOf
analogous to keyof
, by using indexed access types with keyof T
as the key, like so:
type ValueOf<T> = T[keyof T];
给你
type Foo = { a: string, b: number };
type ValueOfFoo = ValueOf<Foo>; // string | number
对于上述问题,您可以使用比 keyof T
更窄的单个键来提取您关心的值类型:
For the question as stated, you can use individual keys, narrower than keyof T
, to extract just the value type you care about:
type sameAsString = Foo['a']; // look up a in Foo
type sameAsNumber = Foo['b']; // look up b in Foo
为了确保键/值对匹配"在函数中正确使用 generics 以及索引访问类型,像这样:
In order to make sure that the key/value pair "match up" properly in a function, you should use generics as well as indexed access types, like this:
declare function onChange<K extends keyof JWT>(key: K, value: JWT[K]): void;
onChange('id', 'def456'); // okay
onChange('expire', new Date(2018, 3, 14)); // okay
onChange('expire', 1337); // error. 1337 not assignable to Date
这个想法是 key
参数允许编译器推断通用的 K
参数.然后它要求 value
匹配 JWT[K]
,你需要的索引访问类型.
The idea is that the key
parameter allows the compiler to infer the generic K
parameter. Then it requires that value
matches JWT[K]
, the indexed access type you need.
这篇关于TypeScript 中是否有类似于“keyof"的“valueof"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!