基于字符串参数的Typescript条件返回类型 [英] Typescript conditional return type based on string argument
问题描述
在使用字符串文字的并集作为输入参数时,删除强制类型转换并将类型放入函数标题中会如何:
When using union of string literals as input argument, what would it take to remove the casts and put the type into the function header:
const get = <T extends "barcode" | "mqtt">(s: T) =>
s === "barcode" ?
<T extends "barcode" ? {scan: () => string} : {pan: () => string}>{scan: () => "we are scanning"} :
<T extends "barcode" ? {scan: () => string} : {pan: () => string}>{pan: () => "we are panning"}
get("barcode").scan() // OK
get("mqtt").pan() // OK
get("barcode").pan() // Error
我遇到了这个问题,试图回答其他人的问题: https://stackoverflow.com/a/55059318/2684980.
I ran into this trying to answer someone else's question: https://stackoverflow.com/a/55059318/2684980.
推荐答案
最干净的解决方案是使用重载代替这种情况(尽管没有比类型断言更安全的类型).您可以在公共签名中使用条件类型,并在实现签名中使用简单的联合.您将需要切换到函数声明,因为函数表达式(箭头或正则表达式)不容易支持重载:
The cleanest solution is such cases (although not any more type safe than the type assertions) is to use overloads instead. You can use conditional types in the public signature, and a simple union in the implementation signature. You will need to switch to a function declaration as function expressions (arrow or regular) don't easily suport overloads:
function get<T extends "barcode" | "mqtt">(s: T): T extends "barcode" ? { scan: () => string } : { pan: () => string }
function get(s: "barcode" | "mqtt"): { scan: () => string } | { pan: () => string } {
return s === "barcode" ?
{ scan: () => "we are scanning" } :
{ pan: () => "we are panning" }
}
get("barcode").scan() // OK
get("mqtt").pan() // OK
get("barcode").pan() // Error
这篇关于基于字符串参数的Typescript条件返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!