基于条件类型的可选参数

Optional parameters based on conditional types

是否可以根据 TypeScript 中的条件类型使函数具有强制参数或可选参数?

这是我目前得到的:

const foo = <T extends string | number>(
    first: T,
    second: T extends string ? boolean : undefined
) => undefined;

foo('foo', true); // ok, as intended
foo(2, true); // not ok, as intended
foo(2, undefined); // ok, as intended
foo(2); // compiler error! I want this to be ok

您可以在 3.1 中使用 Tuples in rest parameters and spread expressions

执行此操作
const foo = <T extends string | number>(
  first: T, 
  ...a: (T extends string ? [boolean] : [undefined?])
) => undefined;

foo('foo', true); // ok, as intended
foo(2, true); // not ok, as intended
foo(2, undefined); // ok, as intended
foo(2); // ok

但更好的方法是使用重载。

function foo2(first: string, second: boolean) : undefined
function foo2(first: number, second?: undefined): undefined
function foo2<T>(first: T, second?: boolean): undefined{
  return undefined
}

foo2('foo', true); // ok, as intended
foo2(2, true); // not ok, as intended
foo2(2, undefined); // ok, as intended
foo2(2); // ok

通过结合@Titian 提供的解决方案,这可以在不实际使用剩余参数的情况下实现:


function foo<T extends string | number>(
    first: T, ...a: T extends string ? [boolean] : [undefined?])
function foo(first: string, second: boolean): undefined {
    return undefined
}

foo('foo', true);  // ok
foo(2, true);      // not ok
foo(2, undefined); // ok
foo(2);            // ok

请注意,在 类 中使用它需要在重载之上 //@ts-ignore