typescript 如何使函数只接受Map到特定类型的键?

zxlwwiss  于 2023-02-13  发布在  TypeScript
关注(0)|答案(1)|浏览(137)

如何使函数只接受Map到特定类型的键?

type Foo = {
    // Arbitrary, can be any type
    foo: number;
    bar: number;
    baz: string;
}

function f<T>(obj: T, key: keyof T) {
    const foo = obj[key] // foo should be type number
}

const x: Foo = {foo: 0, bar: 1, baz: "a"}
f(x, "foo") // OK
f(x, "bar") // OK
f(x, "baz") // Should give error, because x["baz"] is not of type number

我试过扩展T,但无法让它使用参数中的密钥:

function f<T extends {key: number}>(obj: T, key: keyof T) {} // Doesn't work

我也试过从Foo中提取所有的数字字段,并取其中的key,但Extract似乎并不以这种方式工作:

function f<T>(obj: T, key: keyof (Extract<T, number>))) {} // Also doesn't work

这在TypeScript中可能吗?
连接至Playground

eyh26e7m

eyh26e7m1#

有趣的问题!设法解决了这个难题。是的,可以在conditional types的帮助下完成,但要振作起来,这是相当复杂的:

type NumberProp<T> = keyof T extends infer K 
    ? K extends keyof T 
        ? T[K] extends number 
            ? K : never : never : never;

function f<T>(obj: T, key: NumberProp<T>) {
    const foo = obj[key];
}

const x = {foo: 0, bar: 1, baz: "a"};
f(x, "foo"); // OK
f(x, "bar"); // OK
f(x, "baz"); // ERROR

相关问题