在previous question中,我询问了如何分配对象的值和对象的键。现在我已经实现了它,第一个函数在使用keyof
时工作正常,但第二个函数不允许我打开key
来缩小类型。
下面是相关行旁边有注释的示例代码。
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()); // Works!
break;
}
}
function onChange<K extends keyof JWT>(key: K, value: JWT[K]) {
switch (key) {
case 'id':
case 'token':
obj[key] = value + ' (assigned)';
break;
case 'expire':
obj[key] = value.toISOString(); // Error!
break;
}
}
如何实现onChange
功能,以便交换机缩小与上述print
功能类似的类型?
答案 0 :(得分:2)
有点疯狂,但我认为能达到你想要的;)它建立在我对你之前关于valueof
的问题的回答之上。此外,它还会更改onChange
签名以接受{key: K extends string, value: JWT[K]}
类型的对象,而不是单独的key
和value
参数
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()) // Works!
break
default:
return
}
}
type ObjectToUnion<
T extends object,
U = { [K in keyof T]: { key: K; value: T[K] } }
> = U[keyof U]
function onChange(jwt: ObjectToUnion<JWT>) {
switch (jwt.key) {
case 'id': // Try to comment this line and see the error appear at 'exhaustiveCheck'
case 'token':
obj[jwt.key] = jwt.value + ' (assigned)'
return
case 'expire':
obj[jwt.key] = jwt.value.toISOString() // Error!
return
default:
// Optionally add exhaustive check to make sure you have covered all cases :)
const exhaustiveCheck: never = jwt
return
}
}
您可以阅读有关从不输入here的更多信息。
我希望能回答你的问题:)
干杯, 克里斯