首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >打字稿没有正确地进行案例分析

打字稿没有正确地进行案例分析
EN

Stack Overflow用户
提问于 2022-09-18 06:30:17
回答 1查看 55关注 0票数 3

假设我们想要定义一个接受另一个函数及其参数的函数,并输出与该参数一起调用的函数。这是一个很好的例子,我们希望打字稿能做适当的案例分析。见下文。

代码语言:javascript
复制
let fns = {
  A: (x: string) => 'a' + x,
  B: (y: number) => 100 + y
}

type fn = typeof fns[keyof typeof fns]

const combine = <T extends fn>(fn: T, param: Parameters<T>[0]) => {
  return fn(param)
}

问题是,打字本给了我下面这个单词param的错误(在单词返回的行上):Argument of type 'string | number' is not assignable to parameter of type 'never'. Type 'string' is not assignable to type 'never'.ts(2345)

由于某些原因,它将这两种类型的输入合并到一种类型中,而不是理解T只会是一种或另一种。帮助!

EN

回答 1

Stack Overflow用户

发布于 2022-09-18 13:50:45

(使用A和B分别指签名)

TypeScript在这里实际上是正确的,因为T extends fn,而不是,意思是T只能是"A“或"B”。T extends fn是一个约束,这意味着T必须分配给fn。当然,"A“和"B”可以分配给fn,但是类型A | B也可以分配给fn

这意味着有人可以这样调用你的功能:

代码语言:javascript
复制
combine<fn>(fns.A, 0);

如果TypeScript允许这样做,那么这个调用将是有效的!这将导致意想不到的不良行为。但别担心,我有两个可能的解决办法,每一个都有各自的优缺点。

一种是使用外部签名并编写如下内部签名:

代码语言:javascript
复制
function combine<T extends fn>(fn: T, param: Parameters<T>[0]): ReturnType<T>;
function combine<T extends (x: unknown) => R, R>(fn: T, param: Parameters<T>[0]): R {
  return fn(param);
}

这是有点丑陋和不安全,但它的工作,同时保留原来的签名。但是,正如我前面提到的,人们可以用fn类型来称呼它,而不是"A“或"B”。

游乐场

与第一种类似,它使用单独的重载代替。它比第一个稍微好一点,因为它阻止用户用函数联合调用它,但它要输入的内容要多得多。

代码语言:javascript
复制
function combine(fn: typeof fns.A, param: string): string;
function combine(fn: typeof fns.B, param: number): number;
function combine<T extends (x: unknown) => R, R>(fn: T, param: Parameters<T>[0]): R {
  return fn(param)
}

游乐场

也许有更好的解决方案,但我还没喝早咖啡。希望你至少理解为什么这是一个错误,但我仍然会编辑更好的解决方案,当我想到他们的答案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73760581

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档