如何在不使用重载的情况下重构具有不同元数的函数重载?

How to refactor function overloads with different arity without using overloads?

我有一个 arity 不同的 typescript 函数声明:

function f(): void;
function f(code: 0): void;
function f(code: 1, msg: string): void;
function f(code: 0 | 1 = 0, msg?: string): void { /* omit implementation */ }

因此它可以被调用为:

f() // ok
f(0) // ok
f(1, "error message") // ok
f(0, "message") // type error
f(1) // type error

我的问题是如何在不使用函数重载的情况下重构这个函数声明? (例如联合类型、条件类型等)

以下是使用联合类型键入参数组合的方法:

function f(...args: [] | [0] | [1, string]): void { /* omit implementation */ }

Playground

* 带有重载的版本看起来仍然干净多了。

这个呢?

type Message = {code: 0 } | {code: 1, messageText?: string};

const useMessage = (message?: Message) => {};

const usedMessage_0 = useMessage();
const usedMessage_1 = useMessage({code: 0});
const usedMessage_2 = useMessage({code: 1});

const usedMessage_3 = useMessage({code: 0, messageText: 'something'}); // type error
const usedMessage_4 = useMessage({code: 1, messageText: 'something'});