有没有一种方法可以传递一个泛型并推断另一个泛型?

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)

Ole*_*ter 2

您想要实现的目标目前是不可能的(有点可能,请参见下文)。

但是,如果您愿意为 的每个实例化使用额外的变量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 正在获取实例化表达式,尽管不幸的是不允许您的用例,但似乎是朝着允许部分应用泛型类型参数的方向迈出的一步。

操场