我对Typescript比较陌生,想知道:对于简单的curried函数,如:
const add = (a:number) => (b:number):number => a + b;
是否可以同时支持数字和字符串输入,并将输出类型限制为第一种输入类型?
例如:
const add = (a:number | string) => (b:type of a):type of a => a + b;
我对Typescript比较陌生,想知道:对于简单的curried函数,如:
const add = (a:number) => (b:number):number => a + b;
是否可以同时支持数字和字符串输入,并将输出类型限制为第一种输入类型?
例如:
const add = (a:number | string) => (b:type of a):type of a => a + b;
2条答案
按热度按时间w3nuxt5m1#
是的,但我认为你在函数的实现中被类型Assert所困扰。但我们可以精确地确定类型。
乍一看,你会“只是”使用一个泛型类型参数(playground链接):
实际上,这对于以下情况很有效:
但是,如果在调用
add
函数时使用文字,则不起作用:问题是
T
被推断为文字类型1
,而不是number
。您可以通过使用Map类型扩展它来解决这个问题:
现在,所有这些工作:
但这些并没有,正如所期望的:
那么我在上面方便地忽略的“实现”呢?不幸的是,
a + b
不起作用,因为TypeScript不太明白你可以可靠地将+
应用于这些参数。但是你知道你可以,所以你可以通过类型Assert来解决它:我不喜欢类型Assert,并尽可能避免then,但我不知道用上面的方法来避免它。
omqzjyyz2#
通常你需要一个generic type parameter,像这样:
这里的
<T,>
声明了一个泛型类型参数。需要,
来避免带有JSX组件的文件中的语法歧义,但如果您不使用这些组件,则可以删除逗号。对于您的示例,您希望将类型约束为
string | number
,因此您需要type参数的上限:Playground链接
另一种方法,如果你只想使用几个已知类型,并且你不需要完全的泛型,那就是使用函数重载:
Playground链接
对于您的特定示例,有一个问题,因为TypeScript认为如果您编写一个
+
,这可能意味着数字加法或字符串连接,这取决于运行时的类型,这可能是一个错误。所以在这些片段中,你会得到一个类似 “Operator '+' cannot be applied to types 'T' and 'T'" 的错误。一般来说,这是一个很好的策略,因为通常您肯定想要加法而不是串联,反之亦然。我认为你的函数只是一个简单的例子,模糊地添加字符串或数字超出了你的问题的范围。但是如果有问题,请参阅here修复这个错误。