如何在typescript中安全地键入curried函数?特别是关于以下示例
interface Prop {
<T, K extends keyof T>(name: K, object: T): T[K];
<K>(name: K): <T>(object: T) => /* ?? */;
}
const prop: Prop = (key, object) => object[key];
const valid1 = prop('foo', { foo: 'hello' }); // string
const valid = prop('foo')({ foo: 'hello' }); // string
// `never`, since `baz` does not exist in { foo: string }
const invalid = prop('baz')({ foo: 'hello' }); // never发布于 2020-02-13 17:44:00
function prop<T, K extends keyof T>(name: K, obj: T): T[K]
function prop<K extends PropertyKey>(name: K):
<T extends Record<K, unknown>>(obj: T) => T[K]
function prop(name: any, obj?: any) {
if (obj === undefined) {
return (obj: any) => obj[name]
} else {
return obj[name]
}
}
// weak types used in impl for simplicity, as they don't matter for the caller.
// also this function body is not really complexconst valid1 = prop('foo', { foo: 'hello1' }); // string
const valid2 = prop('foo')({ foo: 'hello2' }); // string
const invalid = prop('baz')({ foo: 'hello' }); // compile error, `baz` not in { foo: string } interface Prop {
<T, K extends keyof T>(name: K, obj: T): T[K];
<K extends PropertyKey>(name: K): <T extends Record<K, unknown>>(obj: T) => T[K]
}
const prop: Prop = (name: any, obj?: any) => {
if (obj === undefined) {
return (obj: any) => obj[name]
} else {
return obj[name]
}
}
// weak types used here for simplicity like in first solutionconst valid1 = prop('foo', { foo: 'hello1' }); // string
const valid2 = prop('foo')({ foo: 'hello2' }); // string
const invalid = prop('baz')({ foo: 'hello' }); // never
console.log(valid1, valid2) // hello1 hello2注意:函数重载和函数类型不能完全互换使用(更多信息是here或here)。对于后者,可能需要在函数实现部分使用any注释类型,以说明定义的调用签名中不兼容的返回类型-查看此playground以获取示例。
发布于 2020-02-15 03:44:46
可能有点冗长,但做了它需要做的事情:
interface Prop {
<K extends PropertyKey, T extends {}>(name: K, object: T): K extends keyof T ? T[K] : undefined;
<K extends PropertyKey>(name: K): <T extends {}>(object: T) => K extends keyof T ? T[K] : undefined;
}
declare const prop: Prop;
const invalid = prop('bar')({ foo: 'hello world' });
const valid = prop('foo')({ foo: 'hello world' });
const sLen = prop('length', 'Hello World');
const arity = prop('length')((a: number, b: number, c: number) => a + b + c);https://stackoverflow.com/questions/60203078
复制相似问题