【发布时间】:2017-10-14 09:21:13
【问题描述】:
我正在努力编写一个代码来推断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)
【问题讨论】: