Mac*_*ski 5 types typescript typescript-generics
考虑以下代码:
const selectFrom =
<T>() =>
<U extends Partial<T>>(fields: U) => {
return fields as U;
};
type Item = { a: string; b: string };
// intellisense on the argument Partial<Item>
const x = selectFrom<Item>()({ a: "" });
// typeof x => { a: string }
Run Code Online (Sandbox Code Playgroud)
selectFrom仅当返回另一个函数时,我才能获得我想要的类型。有没有办法实现以下目标签名?
// target signature:
const x = selectFrom<Item>({ a: "" });
// current signature:
const x = selectFrom<Item>()({ a: "" });
Run Code Online (Sandbox Code Playgroud)
您想要实现的目标目前是不可能的(有点可能,请参见下文)。
但是,如果您愿意为 的每个实例化使用额外的变量T,则可以将函数签名与实现分开,并将T类型参数移动为类型别名所需的类型参数,同时保持签名的其余部分通用和限制为Partial<T>:
type selectFrom<T> = <U extends Partial<T>>(fields: U) => U;
type Item = { a: string; b: string };
type Item2 = { answer: 42, question: unknown };
const selectFromI: selectFrom<Item> = (fields) => fields;
const selectFromJ: selectFrom<Item2> = (fields) => fields;
// intellisense on the argument Partial<Item>
const y = selectFromI({ a: "" });
// ^? const y: { a: string; }
const x = selectFromJ({ answer: 42 });
// ^? const x: { answer: 42; }
Run Code Online (Sandbox Code Playgroud)
这并不理想,但至少您不需要每次想要使用该selectFrom函数时都进行额外的“空”调用(并且您可能会发现自己想要将第一个调用提取到变量中)。
与此相关的是,TypeScript 4.7 正在获取实例化表达式,尽管不幸的是不允许您的用例,但似乎是朝着允许部分应用泛型类型参数的方向迈出的一步。