抱歉,标题复杂,我想不出更好的标题。
其他背景:这需要在TS 2.8.4上工作
我需要一些有关映射类型的帮助
// Input types:
type FunctionOrObject<Arg, Result> =
| ((arg: Arg) => Partial<Result>)
| Partial<Result>;
interface ExampleArg {
disabled: boolean;
}
interface ExampleResult {
root: string;
sub: string;
}
type FuncOrObj = FunctionOrObject<ExampleArg, ExampleResult>;
type Standalone = ExampleResult;
// Expected should have the type (arg: Arg) => Partial<Result>
type Expected = MagicMappingType<FuncOrObj >;
// Expected2 should have the type (...args: any[]) => Partial<Result>
type Expected2 = MagicMappingType<Standalone>;
现在我想出了这个方法,但是它不能很好地工作
type _TrimToFunction<T> = T extends (...args: any[]) => any ? T : never;
// Expected has type (arg: ExampleArg) => Partial<ExampleResult> - Correct!
type Expected = _TrimToFunction<FuncOrObj>;
// Expected2 is never - Wrong!
type Expected2 = _TrimToFunction<Standalone>;
这显然是因为独立接口ExampleResult
没有通过_TrimToFunction
的条件,因此被映射到never
。但是,如果我将_TrimToFunction
更改为此:
type _TrimToFunction<T> = T extends (...args: any[]) => any ? T : (...args: any[]) => T;
映射独立接口会产生正确的结果,但是现在对于FuncOrObj
类型,我得到了错误的结果:
type Expected =
| ((arg: ExampleArg) => Partial<ExampleResult>)
| ((...args: any[]) => Partial<Partial<ExampleArg>>)
type Expected2 = (...args: any[]) => Partial<ExampleResult>
这是由于FuncOrObj
联合的第二部分未通过条件检查而被映射为“ else”类型引起的。
我想使用TS 2.8实现什么目标?
答案 0 :(得分:1)
在最后一个代码段中获得意外类型的原因是,如果type参数为赤裸裸,则条件类型将在联合上分布。阅读docs以获得更多信息。
简单的解决方案是稍微改变条件。我们可以使用Extract
。如果我们可以从Function
中提取一个T
,则返回该值;如果不能,则返回一个返回Partial<T>
type _TrimToFunction<T> = Extract<T, Function> extends never ? (...args: any[]) => Partial<T>: Extract<T,Function>;
// Expected has type (arg: ExampleArg) => Partial<ExampleResult> - Correct!
type Expected3 = _TrimToFunction<FuncOrObj>;
// Expected2 is (...args: any[]) => Partial<ExampleResult>
type Expected4 = _TrimToFunction<Standalone>;