【问题标题】:Typescript conditional mapped types loses return type information打字稿条件映射类型丢失返回类型信息
【发布时间】:2019-10-25 05:15:30
【问题描述】:

我正试图围绕条件映射类型展开思考。如果我有一个类型定义为:

type StringyProps<T> = { [K in keyof T]: T[K] extends string ? K : never }[keyof T];

[keyof T] 最后的构造是做什么的?如何找到有关您可以用它做什么的文档?

另外,我写了一个函数:

function getString<T>(thing: T, prop: StringyProps<T>): string {
  return thing[prop] as string;
}

如果我有如下界面:

interface Something {
  name: string,
  id: string,
  age: number,
  weight: number
}

我收到以下编译时错误:

console.log(getString(pippy, "name")); // ok
console.log(getString(pippy, "age")); // age is not assignable to parameter of type "name" | "id"

这太棒了,但我的函数无法编译,因为将 StringyProp 的值分配给字符串可能是错误的。如果我将返回值更改为return thing[prop] as unknown as string,它会返回正确的值。

我怎样才能构造它,这样我就不必断言未知和重新断言字符串?

【问题讨论】:

    标签: typescript conditional-types mapped-types


    【解决方案1】:

    Typescript 无法遵循 StringyProps&lt;T&gt; 仅代表 string prfoperty 键的事实。最好的解决方案是使用类型断言:

    function getString<T>(thing: T, prop: StringyProps<T>): string {
      return thing[prop] as unknown as string;
    }
    

    你也可以稍微改变一下类型,但是intelisense不会再建议key了所以我觉得不值得,调用站点体验更重要:

    function getString<K extends PropertyKey>(thing: Record<K, string>, prop: K): string {
      return thing[prop]; // ok no assertion
    }
    
    console.log(getString(pippy, "name")); // ok
    console.log(getString(pippy, "age")); //err
    

    【讨论】:

    • 这是有道理的。这肯定会要求编译器跟踪很多。我真的很惊讶我能用这个做多少!我同意你的观点,我更关心呼叫站点体验。如果我非常担心,我可以接受(model: t) =&gt; string 类型的选择器。我只是打字稿的超级新手,深入研究这样的事情可以帮助我掌握方向。非常感谢!!
    • @D.Patrick 欢迎您,不要忘记投票并标记为已回答 :)
    猜你喜欢
    • 2021-09-18
    • 2019-11-19
    • 2022-12-07
    • 2022-08-16
    • 1970-01-01
    • 2022-07-07
    • 2021-09-17
    • 2020-06-29
    • 2022-08-17
    相关资源
    最近更新 更多