基于可选参数的打字稿函数返回类型



如何解决不良类型?

TS 沙盒。

interface X<T> {
abc:T
}
declare function deepLock<Obj extends Record<string, any>,>(obj: Obj): X<Obj>;
declare function deepLock<Obj extends Record<string, any>,>(obj: Obj, options: {}): X<Obj>;
declare function deepLock<
Obj extends Record<string, any>,
Action extends "freeze" | "seal" | "preventExtensions",
Options extends { action?: Action }
>(obj: Obj, options?: Options): Action extends 'freeze' ? X<Obj> : Obj
// ok
const x = deepLock({}) // expect X<{}>
const x2 = deepLock({}, {}) // expect X<{}>
// need to be fixed
const x3 = deepLock({}, {action: 'freeze'}) // expect X<{}>
const x4 = deepLock({}, {action: 'seal'}) // expect Obj
const x5 = deepLock({}, {action: 'preventExtensions'}) // expect Obj

因此,您只需稍微调整函数定义以:

declare function deepLock<
Obj extends Record<string, any>,
Action extends "seal" | "preventExtensions" | "freeze",
>(obj: Obj, options?: { action?: Action }): 'freeze' extends Action ? X<Obj> : Obj;

你面临的问题是Action正在扩展"seal" | "preventExtensions" | "freeze"因此根据定义Action extends "freeze"永远是正确的,因为它总是扩展它。

因此,为了正确缩小类型,您必须做"freeze" extends Action这仅适用于三种行动可能性之一。

游乐场链接

希望这是有道理的