gpt4 book ai didi

typescript - 使用泛型和 keyof 时推断回调参数的属性类型

转载 作者:搜寻专家 更新时间:2023-10-30 21:49:56 26 4
gpt4 key购买 nike

我正在努力编写一个代码来推断 args.value 的类型里面if范围:

class Foo {
public id: number;
public name: string;
public birth: Date;
}

interface ISetEventArgs<T> {
field: keyof T;
value: T[keyof T];
}

function bind<T>(obj: T, event: "set", handler: (args: ISetEventArgs<T>) => void): void {
// Void
}

let f: Foo = new Foo();

bind<Foo>(f, "set", (args: IArgs<Foo>): void => {
if (args.field === "id") {
let id: number = args.value; // Error: Type 'string | number | Date' is not assignable to type 'number'.
}
else if (args.field === "name") {
// ...
}
else if (args.field === "birth") {
// ...
}
});

我试图通过写这样的东西来解决这种情况,但感觉不对:

function getValue<T, K extends keyof T>(value: T[keyof T], key: K): T[K] {
return value;
}

// Usage:
if (args.field === "id") {
let id: number = getValue<Foo, "id">(args.value, args.field); // Correct type.
// Can also be used as: getValue<Foo, "id">(args.value, "id");
}

有什么想法吗?即使解决方案需要使用辅助函数,我也真的希望能够以更干净的方式使用它,例如(如果可能)getValue<Foo, "id">(args.value)getValue(args.value, args.field)

最佳答案

我认为如果没有辅助函数就无法完成 - typescript 类型推断没有考虑到 fieldvalue 的类型是相互依赖的。

所以你必须使用所谓的user-defined type guard function明确表达类型关系:

class Foo {
public id: number;
public name: string;
public birth: Date;
}

interface ISetEventArgs<T> {
field: keyof T;
value: T[keyof T];
}

function bind<T>(obj: T, event: "set", handler: (args: ISetEventArgs<T>) => void): void {
// Void
}

let f: Foo = new Foo();

// type guard
function argsForField<T, F extends keyof T>(args: ISetEventArgs<T>, field: F):
args is { field: F; value: T[F]} {
return args.field === field;
}

bind<Foo>(f, "set", (args: ISetEventArgs<Foo>): void => {
if (argsForField(args, "id")) {
let id: number = args.value; //no error
}
else if (argsForField(args, "name")) {
let name: string = args.value
}
else if (argsForField(args, "birth")) {
let birth: Date = args.value;
}
});

关于typescript - 使用泛型和 keyof 时推断回调参数的属性类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46739105/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com