我可以使用 extends keyof Type 推断值的类型吗 [英] Can I infer the type of a value using extends keyof Type
问题描述
在上一个问题中,我询问了如何分配对象的值和对象的键.现在我已经实现了它,第一个函数在使用 keyof
时工作正常,但第二个函数不允许我打开 key
来缩小类型.
下面是在相关行旁边有注释的示例代码.
type JWT = { id: string, token: string, expire: Date };const obj: JWT = { id: 'abc123', token: 'tk01', expire: new Date(2018, 2, 14) };功能打印(键:JWT的键){开关(键){案例ID':案例令牌":console.log(obj[key].toUpperCase());休息;案例过期":console.log(obj[key].toISOString());//有效!休息;}}function onChange(key: K, value: JWT[K]) {开关(键){案例ID':案例令牌":obj[key] = value + '(赋值)';休息;案例过期":obj[key] = value.toISOString();//错误!休息;}}
如何实现onChange
函数,让switch缩小类似于上面print
函数的类型?
有点疯狂,但我认为实现了你想要的 ;) 它建立在我对你之前关于 valueof
的问题的回答之上.它还更改 onChange
签名以接受 {key: K extends string, value: JWT[K]}
类型的对象,而不是单独的 key
> 和 value
参数
type JWT = { id: string;令牌:字符串;到期日期 }const obj: JWT = { id: 'abc123', token: 'tk01', expire: new Date(2018, 2, 14) }功能打印(键:JWT的键){开关(键){案例ID':案例令牌":console.log(obj[key].toUpperCase())休息案例过期":console.log(obj[key].toISOString())//有效!休息默认:返回}}输入 ObjectToUnion) {开关(jwt.key){case 'id'://尝试注释此行并查看错误出现在 'exhaustiveCheck'案例令牌":obj[jwt.key] = jwt.value + '(赋值)'返回案例过期":obj[jwt.key] = jwt.value.toISOString()//错误!返回默认://可选地添加详尽检查以确保您已涵盖所有情况:)const彻底检查:从不= jwt返回}}
您可以在此处阅读更多关于从不输入的信息.>
我希望能回答你的问题:)
干杯,克里斯
In a previous question, I asked about assigning a value of a object and the key of an object. Now that I have implemented it, the first function works fine when using the keyof
but the second does not let me switch on the key
to narrow down the type.
Below is example code that has comments next to the relevant lines.
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;
}
}
How can I implement the onChange
function so that switch will narrow down the type similar to the print
function above?
A bit crazy but I think achieves what you desire ;) It builds upon my answer to your previous question about valueof
. Also it changes onChange
signature to accept an object of type {key: K extends string, value: JWT[K]}
, instead of separate key
and value
parameters
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
}
}
You can read more about never type here.
I hope that answers your question :)
Cheers, Chris
这篇关于我可以使用 extends keyof Type 推断值的类型吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!