这篇文章适用于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
以来,它失败了:
TS2349:无法调用类型缺少调用签名的表达式 . 输入'((arg:Command <“a”>)=>数字)| ((arg:Command <“b”>)=> string)'没有兼容的呼叫签名 .
1 回答
我没有足够聪明地意识到
handlers[a.kind]
的类型与a
相关 .请考虑以下有效但令人讨厌的代码:
从
Key extends keyof HashType
开始,Key
可以等于keyof HashType
. 请注意,给出的参数是Command<keyof HashType>
,即使它既不是Command<"a">
也不是Command<"b">
. 编译器无法保证handlers[a.kind]
适用于a
.这可能是现实生活中使用代码的问题吗?可能不是 . 如果没有,您可以声称您比编译器更了解并使用type assertion:
现在代码编译愉快 . 如果你担心有人会在代码中传递过多的参数,那么就有办法解决它 . 但它可能不值得 .
希望有所帮助!有关类似问题,请参阅this question .