我正在编写许多函数(用于服务器请求),每个函数返回类型都扩展某种类型。
我希望 typescript 限制返回类型以扩展预定义的已知类型,但我希望 typescript 采用返回类型的推断类型(因为它可能更准确)。
例如,假设所有函数都必须返回字符串,因此:
type myFuncsType = (...args: any) => string
每个函数都必须扩展此类型。
现在假设我的函数始终返回一个常量字符串:
const myFunc1 = () => "MyString" as const
// the type is inffered:
const myVal = myFunc1()
// typeof myVal = "MyString"
我们还说过,我们的函数必须扩展预定义的已知类型(myFuncsType
),但是在分配类型时,通用类型会接管推断的准确类型,这是我想避免的:
const myFunc1: myFuncsType = () => "MyString" as const
const myVal = myFunc1()
// typeof myVal = string
我尝试用泛型解决这个问题,但是泛型需要传递预定义类型,并且返回类型在声明期间不可用。
如何限制返回类型以扩展预定义类型,但返回从声明中推断出的确切返回类型?
最佳答案
因为 MyFuncsType
不是 union ,如果您annotate具有该类型的 myFunc1
变量,编译器将始终将该变量视为该类型。它不narrow基于分配给它的特定值的变量,而是将其一直扩展到带注释的类型。所以您不想注释 myFunc1
。
您真正想做的不是注释,而是检查 myFunc1
是否可分配给 MyFuncsType
,而不扩大它。 TypeScript 中没有内置运算符可以执行此操作;请参阅microsoft/TypeScript#7481对于这样的功能的请求。但是您可以编写自己的辅助函数,其行为如下:
type MyFuncsType = (...args: any) => string
const asMyFuncsType = <T extends MyFuncsType>(t: T) => t;
因此,您可以编写 const f = asMyFuncsType(...)
来代替 const f: MyFuncsType = ...
。 asMyFuncsType()
函数仅返回其输入而不更改其类型,但它会检查该类型是否可分配给 MyFuncsType
,因此它会捕获错误:
const badFunc = asMyFuncsType(() => 123); // error!
// -------------------------------> ~~~
// Type 'number' is not assignable to type 'string'
const myFunc1 = asMyFuncsType(() => "MyString" as const); // okay
const myVal = myFunc1()
// typeof myVal = "MyString"
关于 typescript 返回分配函数的推断类型,但限制返回类型以扩展预定义类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68651574/