typescript - 打字稿错误 - 可以用不同的约束子类型实例化
问题描述
有时基于代码,我知道返回值是什么,并希望使用以下方法指定它:
getSmth<string>(1)
并不是
getSmth(1) as string
但不确定如何正确执行
- 问题。如果我正确扩展和返回,为什么会出现错误?
Type 'null' is not assignable to type 'T'.
'null' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | null'.(2322)
例子
const getName = (id: number) : string | null => null
const getSmth = <T extends string | null = string | null>(id: number | null): T => {
if (!id) {
return null;
}
return getName(id);
};
const x1 = getSmth(1) // should be string | null
const x2 = getSmth<null>(1) // should be null
const x3 = getSmth<string>(1) // should be string
- 问题。为什么会出现这种断言?
const getSmth2 = <T extends string | null = string | null>(id: number | null): T => {
if (!id) {
return null as T;
}
return getName(id) as T;
};
const y1: string = getSmth2(1) // why getSmth2 asserts to string when return type should bestring | null
解决方案
如果我正确扩展和返回,为什么会出现错误?
T
由于约束,不保证可以为空。例如,string
扩展string | null
:
// true
type X = string extends string | null ? true : false;
因此,虽然您给出的默认值T
是可以为空的,但编译器无法确保这对于所有可能T
的 s 都是正确的。事实上,这正是你正在尝试做的事情:通过string
. 但是一旦T = string
,返回null
将不再有效。
您可以在实现中键入断言以使其工作。不过,这只会让编译器关闭它确实正确的东西,但如果这是你想要做的:
const getSmth = <T extends string | null = string | null>(id: number | null): T => {
if (!id) {
return null as T;
}
return getName(id) as T;
};
- 问题。为什么会出现这种断言?
本质上,这是同一个问题。这里补充一点,编译器使用左边声明的类型来推断泛型类型参数:
// T inferred to be string
const y1: string = getSmth2(1);
// T is inferred to be string | null
const y2: string | null = getSmth2(1);
您期望T
使用默认值,在这种情况下会发生这种情况:
// string | null
const y3 = getSmth2(1);
推荐阅读
- r - R从数据框中创建一个命名列表
- swiftui - 如何隐藏 Digital Crown 滚动指示器?
- matlab - 我的递归 ARX 有问题。我有“没有足够的输入参数”错误。所有的 I/O 都是给定的,我必须全部使用它们
- android - 没有附加适配器,在片段上跳过布局
- sas - SAS MMYYSW。格式而不是信息?
- rust - Rust - 为什么借用 &mut 两次时它不会给我一个错误
- javascript - HTML表格下拉过滤
- r - 将不同的对象转换为日期格式
- c# - 使用弹出表单、MVC 和 AJAX 上传文件始终为“NULL”
- gitlab - 如何在fastlane fastfile中使用gitlab CI环境变量?