自TypeScript 2.7起缺少类型签名 [英] Lacking type signature since TypeScript 2.7

查看:90
本文介绍了自TypeScript 2.7起缺少类型签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这部分内容适用于TypeScript 2.6:

This piece works in TypeScript 2.6:

function resolver<Key extends keyof HashType>(a: Command<Key>): HashType[Key]['out'] {
  return handlers[a.kind](a);
}


const handlers: {[k in keyof HashType]: (arg: Command<k>) => HashType[k]['out']} = {
  a: arg => 1,
  b: arg => ''
};

type Command<Key extends keyof HashType> = HashType[Key]['in'] & { kind: Key }


type HashType = {
  a: { in: { someString: string }, out: number }
  b: { in: { someNumber: number }, out: string }
}

但是,由于2.7,它失败并显示:

However, since 2.7, it fails with:

TS2349:无法调用类型缺少调用签名的表达式. 键入'(((arg:Command<"a">)=>数字)| ((arg:Command<"b">)=> 字符串)'没有兼容的呼叫签名.

TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((arg: Command<"a">) => number) | ((arg: Command<"b">) => string)' has no compatible call signatures.

推荐答案

对于在TypeScript 2.6中使用此功能的原因,我没有一个很好的了解,但是现在失败的原因是因为编译器可以保护您免受不太可能发生的事情的侵害.发生,并且无论如何还不够聪明,无法意识到handlers[a.kind]的类型与a相关.

I don't have a great handle on why this worked in TypeScript 2.6, but the reason this fails now is because the compiler is protecting you against something unlikely to happen, and in any case isn't smart enough to realize that the type of handlers[a.kind] is correlated with a.

考虑以下有效但令人讨厌的代码:

Consider the following valid but obnoxious code:

const resolved = resolver<"a" | "b">({ someString: "whoops", kind: "b" });

由于Key extends keyof HashTypeKey可以等于keyof HashType.并请注意,给定的参数是Command<keyof HashType>,即使它既不是Command<"a">也不是Command<"b">.编译器不能保证handlers[a.kind]将适用于a.

Since Key extends keyof HashType, Key can be equal to keyof HashType. And note that the argument given is a Command<keyof HashType> even though it is neither a Command<"a"> or a Command<"b">. The compiler cannot guarantee that that handlers[a.kind] will be applicable to a.

在现实生活中使用代码是否有可能成为问题?可能不是.如果不是,您可以声称您对编译器了解更多,并使用

Is that likely to be an issue in real-life use of the code? Probably not. If not, you can claim that you know more than the compiler and use a type assertion:

function resolver<Key extends keyof HashType>(a: Command<Key>): HashType[Key]['out'] {
  const handler = handlers[a.kind] as (arg: Command<Key>) => HashType[Key]['out'];
  return handler(a);
}

现在,代码可以愉快地编译了.如果您 担心有人将太宽的参数传递给代码,则有很多解决方法.但这可能不值得.

Now the code compiles happily. If you are worried about someone passing a too-wide argument to the code, there are ways around it. But it's probably not worth it.

希望有帮助!对于类似的问题,请参见此问题.

Hope that helps! For a similar issue, see this question.

这篇关于自TypeScript 2.7起缺少类型签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆