typescript - 如果块范围类型不通过泛型反映
问题描述
class Foo {
asdf: string;
}
class Bar {
qwerty: number;
}
export type EntityTypeName = 'Foo' | 'Bar';
export type EntityType = Foo | Bar;
export type EntityTypeByName<N> =
N extends 'Foo' ? Foo :
N extends 'Bar' ? Bar :
any;
class Wrapper <N extends EntityTypeName = EntityTypeName, T extends EntityType = EntityTypeByName<N>> {
entityTypeName: N;
entity: T;
}
const wrapper1 = new Wrapper<'Foo'>();
wrapper1.entityTypeName; // "Foo"
wrapper1.entity; // Foo
const wrapper2 = new Wrapper();
if (wrapper2.entityTypeName === 'Foo') {
wrapper2.entityTypeName; // "Foo"
wrapper2.entity; // Foo | Bar (expect Foo)
}
见:https ://stackblitz.com/edit/typescript-sqd5uf
我希望第 39 行会Foo
在鼠标悬停时显示类型,因为它位于从第 37 行开始的 if 块中,并且因为T
第 25 行的泛型在第 20 行被EntityTypeByName<N>
定义。有没有办法完成第 39 行显示类型Foo
?
解决方案
你想要的行为是不正确的。既然wrapper2
是 a Wrapper<"Foo" | "Bar", Foo | Bar>
,那么 to be 是有效的wrapper2.entityTypeName
,"Foo"
但wrapper2.entity
to be a是有效的Bar
。要捕获 和 之间的关系entityTypeName
,entity
您需要使用可区分的联合类型:
type Wrapper<N extends EntityTypeName = EntityTypeName> =
{[P in N]: {entityTypeName: P, entity: EntityTypeByName<P>}}[N];
let wrapper1: Wrapper<'Foo'>;
wrapper1.entityTypeName; // "Foo"
wrapper1.entity; // Foo
let wrapper2: Wrapper;
if (wrapper2.entityTypeName === 'Foo') {
wrapper2.entityTypeName; // "Foo"
wrapper2.entity; // Foo
}
推荐阅读
- javascript - TypeError:无法读取 YoutubeDataAPI 上未定义的属性“列表”
- java - 修复依赖解析错误 - 重复类错误
- scala - 使用 scalatest Flatspec 的杰克逊数据绑定错误
- go - 如何使用备用 go.mod 文件进行本地开发?
- webpack - 如何在 Gulp 中为 webpack-stream 设置多个条目?
- google-cloud-automl - 在多个数据集上训练 Google-Cloud-Automl 模型
- php - Symfony 5 和 Doctrine ODM 中的 PUT 操作
- flutter - 为没有 Cognito 身份池的现有用户池配置 amplify-flutter
- python - 在 Python 中使用空行作为分隔符将文本文件转换为列表
- python - 您如何根据熊猫中另一列的值范围来计算一个列中的值?