gpt4 book ai didi

typescript - 使用 Typescript 从 switch case 返回类型推断

转载 作者:行者123 更新时间:2023-12-05 08:39:52 25 4
gpt4 key购买 nike

函数类型

type fn01 = (name: string) => void
type fn02 = (age: string) => void
type fn03 = (description: number) => void

我有这个案例:

type Options = 'op1' | 'op2' | 'op3'

const test = (options) => {
switch(options) {
case 'op1':
return fn01
case 'op2':
return fn02
case 'op3':
return fn03
default
return null;
}
}

函数用法:

const chosenFN = test('op1');

choseFN()

当使用 chosenFN 时,它应该显示属于 switch case 的函数类型,而不是显示所有类型的交集。

我错过了什么?我认为由于使用的函数在 switch case 内部,它会根据传递的参数推断出正确的类型。

谢谢,热南

最佳答案

编译器通常不会根据输入的特定值来推断函数返回类型。 Control flow type analysis用于缩小函数实现中具体类型变量的类型,因此 switch 语句用于了解 options 恰好是 op2(例如)在相关的 case block 中,但是控制流分析对函数的返回类型没有太大作用。

通常,函数的推断返回类型是从函数返回的所有类型的联合,与控制流分析无关。这意味着 test() 的签名被推断为类似于 function test(options: Options): fn01 | fn02 | fn03 |空

当你去实际调用fn01 | 类型的函数时fn02 | fn03 | null,你会遇到麻烦。用the --strictNullChecks compiler option上,您根本无法调用它(您可能应该使用--strict 编译器选项,因为它们会捕获错误)。

假设你有一个fn01 |类型的函数fn02 | fn03(并且你已经验证它不是null),你仍然不能真正调用它。对调用函数联合的支持是 improved在 TypeScript 3.5 中,但是,您可以传递给函数联合的唯一安全的东西是其参数的交集。交集 string & string & number 没有成员(在 JavaScript 中没有值既是 string 又是 number),这意味着它是从不,因此它是完全不可调用的。


所以,这就是它不起作用的原因。要修复它,您要么必须使用 function overloads , 或者将函数注释为 generic ,其中 options 是通用类型 O extends Options

重载很容易,但它们并不是真正的类型安全。

泛型类型有可能更安全,但当您使用 switch 时就不是这样了,它公开了一个 current limitation of TypeScript因此,控制流分析无法缩小泛型变量的类型。

最安全的方法是使用映射对象而不是 switch 语句:

const test = <O extends Options>(options: O) => ({
op1: fn01,
op2: fn02,
op3: fn03
}[options]);

这被正确地推断为一个通用函数,其中每个输入类型映射到一个特定的函数输出类型:

const chosenFN = test('op1'); // (name: string) => void
chosenFN("okay") // okay
test('op2')("age is a string I guess"); // okay
test('op3')(8675309); // okay

Link to code

关于typescript - 使用 Typescript 从 switch case 返回类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58673034/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com