我可以使用 extends keyof Type 推断值的类型吗 [英] Can I infer the type of a value using extends keyof Type

查看:23
本文介绍了我可以使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆