typescript - 打字稿方法中如何推断通用返回值?
问题描述
我想更好地理解 typescript 如何用泛型推断返回类型。如果一个使用泛型类型作为返回值的方法在没有泛型类型参数的情况下被调用,那么 typescript 是如何推断返回类型的?我知道泛型参数可以很容易地通过发送的类型推断出来,但如果没有提供泛型类型参数,则无法推断返回参数。
// Call:
this.getSomething(value);
// Method signature:
getSomething<T>(inParameter: string): T {
...
}
解决方案
让我们考虑一下getSomething()
方法:
getSomething<T>(inParameter: string): T {
return null!; // <-- this isn't safe, whatever you put here
}
你没有在那里展示实现,所以我不确定它认为它在做什么。但是签名本身是可疑的......getSomething()
声称它可以T
为调用者选择的任何类型(或编译器为调用者推断)返回一个类型值,只需一个string
输入。这不太可能是真的,或者至少不能轻易地被验证为类型安全。
我的意思是,没有什么能阻止我写作this.getSomething<string>("abc")
,然后this.getSomething<number>("abc")
。但是由于类型系统在将 TypeScript 编译为 JavaScript 时被删除this.getSomething("abc")
,所以这两个调用都将作为. 可能这两个调用的结果相同,并且由于该结果不可能同时是 astring
和a number
,因此这些 TypeScript 调用中至少有一个是错误的。
但是,让我们继续讨论您的问题:
如果您只是调用this.getSomething(value)
,推理可能会失败,并且T
会变成{}
或unknown
取决于您使用的 TypeScript 版本。
const hmm = this.getSomething("value"); // const hmm: unknown
// inference fails, T inferred as unknown
如果您调用const t: string = this.getSomething(value)
它将使用上下文类型
来t
决定T
必须是string
:
const t: string = this.getSomething("value");
// contextual typing, T is inferred as string
但是,如果调用者提供了一个类型的参数T
或其他可能本身可能产生一个类型的值的东西,那么这对安全和推理都更好T
。例如:
getSomethingReasonable<T>(inParameter: string, tArray: T[]): T {
return tArray[inParameter.length];
}
const okay = this.getSomethingReasonable("value", [1,2,3,4,5,6,7,8]);
// inference on tArray, T is number
它更安全,因为输入tArray
提供了一种运行时机制,T
即使在类型擦除的情况下也可以生成类型值。而且,正如您所指出的,这是推断T
.
好的,希望有帮助。祝你好运!
推荐阅读
- c++ - wcstof 精度
- orc - Azure SQL 数据仓库 (Synapse Analytics) 使用 ORC 表的 Polybase 性能
- spring - Spring BCryptPasswordEncoder - 任何方式来配置散列生成的轮数?
- android - Android:更改复选框颜色(框背景和刻度线颜色)
- react-native - 反应原生元素 - 为 listItem 中的徽章背景颜色应用条件样式
- node.js - Angular CLI ng 新错误 EEXIST:文件已存在 Windows 10
- database - SQLSTATE[HY000] [2002] 由于目标机器主动拒绝,无法建立连接。(SQL: select * from `gallery` where `status` = 1)
- sed - 如何检查sed中输入的是数字还是字母
- django - 如何在 swagger drf_yasg(维护 CSRF)中禁用/删除授权按钮 - django
- python - 为什么我的默认 PATH 中有一些 /Library/Frameworks/Python.framework/Versions/XX/bin?