【问题标题】:This condition will always return 'false' since the types 'T[keyof T]' and 'string' have no overlap此条件将始终返回 'false',因为类型 'T[keyof T]' 和 'string' 没有重叠
【发布时间】:2021-04-20 06:11:20
【问题描述】:

我在JS中有如下fn,基本上是想通过它的key在数组中找到一个对象。

我收到以下错误:

此条件将始终返回 'false',因为类型 'T[keyof T]' 和 'string' 没有重叠

有什么办法解决吗?

   export const findObjectByKey = <T>(
      prop: keyof T,
      value: string,
      data: ReadonlyArray<T>
    ) => data.find((x) => x[prop] === value);

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您可以通过为 prop(传统上为 K)声明扩展 keyof T 的类型来告诉 TypeScript value 的值:

    export const findObjectByKey = <T, K extends keyof T>(
        prop: K,
        value: T[K],
        data: ReadonlyArray<T>
    ) => data.find((x) => x[prop] === value);
    

    现在 TypeScript 知道比较没问题(它适用于类型不是 string 的属性,尽管您现在可能不需要它):

    // Works, `obj.foo` is string
    findObjectByKey("foo", "x", [{ foo: "y" }])
    // Works, `obj[42]` is string
    findObjectByKey(42, "x", ["1"])
    // Works, `obj.foo` is number
    findObjectByKey("foo", 42, [{ foo: 27, bar: "x" }])
    // Error as desired, `obj.foo` is number but `value` is string
    findObjectByKey("foo", "x", [{ foo: 27, bar: "x" }])
    //                     ^−−−−− Argument of type 'string' is not assignable to parameter of type 'number'.
    

    Playground link

    非常感谢Aleksey L. 指出我们可以做得更好,而不仅仅是属性值类型的联合。

    【讨论】:

    • 为了收紧value类型,我们也可以为属性引入泛型类型参数typescriptlang.org/play?jsx=0#code/…
    • 谢谢@AlekseyL。!我认为这是可能的,但是...您想发布答案,还是希望我编辑以上内容?
    【解决方案2】:

    我会使用另一个泛型来表示 prop 在 T 上的关联值是一个字符串,因此允许 x[prop]

    export const findObjectByKey = <P extends keyof any, T extends Record<P, string>>(
      prop: P,
      value: string,
      data: ReadonlyArray<T>
    ) => data.find((x) => x[prop] === value);
    
    findObjectByKey('foo', 'val', [{ foo: 'val', bar: 'bar' }])
    

    【讨论】:

      【解决方案3】:

      你可以尝试以下,基本上你需要告诉TS根据T中的prop类型输入value

      export const findObjectByKey = <T>(
        prop: keyof T,
        value: T[typeof prop],
        data: ReadonlyArray<T>
      ) => data.find((x) => x[prop] === value)
      

      Play ground link

      【讨论】:

        猜你喜欢
        • 2019-07-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-29
        • 2020-12-11
        • 2020-01-05
        • 1970-01-01
        • 2021-09-16
        相关资源
        最近更新 更多