【问题标题】:Typescript keyof generic AND extends a typeTypescript keyof generic AND 扩展了一个类型
【发布时间】:2021-09-29 00:28:20
【问题描述】:

给定如下界面:

interface Payload {
  value1: number;
  value2: string;
}

我想创建一个函数,它接受 Payload[] 并且只接受扩展 numberPayload 的键。像这样的:

function F<T, K extends keyof T, T[K] extends number>(arr: T[], property: K) {
  //
}

function foo(payloads: Payload[]) {
  F(payloads, "value1"); // should work
  F(payloads, "value2"); // should not work because value2 is a string
  F(payloads, "value3"); // should not work because value3 not in Payload[]
}

See playground

【问题讨论】:

    标签: typescript


    【解决方案1】:

    我使用仅保留 numbernumber | undefined 属性的映射类型来实现这一点:

    interface Payload {
        value1: number;
        value2: string;
        value3?: number;
        value4?: string;
    }
    
    type NumberOnly<T> = {
        // Doesn't allow `number | undefined` if `strictNullChecks` is enabled
        //[key in keyof T as T[key] extends number ? key : never]: T[key];
        // This will always allow `number | undefined` on top of just `number`
        [key in keyof T as T[key] extends number | undefined ? key : never]: T[key];
    };
    
    function F<T extends NumberOnly<any>, K extends keyof NumberOnly<T>>(arr: T[], property: K) {
        const value = arr[0][property];
        return value;
    }
    
    function foo(payloads: Payload[]) {
        F(payloads, "value1"); // should work
        F(payloads, "value2"); // should not work because value2 is a string
        F(payloads, "value3"); // should work (you can filter undefined if you want)
        F(payloads, "value4"); // should not work because value4 is a string
        F(payloads, "value5"); // should not work because value5 not in Payload[]
    }
    

    从技术上讲,它也会接受value5: undefined,但不接受例如value5: string | undefined,一个无关紧要的极端情况。

    它只接受value1value3

    基于this answer 使用TypeScript 4.1 feature

    【讨论】:

    • 虽然没有tsconfig.json,但我也在使用v4.3.5,现在我检查了,启用strictNullChecks确实会破坏number | undefined。我将更新我的答案(和屏幕截图)以修复/提及此问题,同时解决您无法编制索引的问题。
    • 太棒了!我无法破解的部分是T extends NumberOnly&lt;any&gt;。 FWIW,here's a generic version.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-12
    • 2018-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多