typescript - Typescript 基于嵌套成员推断父类型
问题描述
Typescript 可以根据您在 if 语句中提出的问题来推断值的类型。例如,一个对象的一个成员可以基于另一个成员来推断:
type ChildType = 'a' | 'b';
type Child<T extends ChildType> = T extends 'a' ? { type: 'a', color: 'blue' } : T extends 'b' ? { type: 'b', color: 'red' } : never;
interface Parent<T extends Child<ChildType>> {
child: T extends Child<infer R> ? Child<R> : never;
}
function test<T extends Parent<Child<any>>>(parent: T) {
if (parent.child.type === 'a') {
parent.child.color === 'red'; // complains because should be blue
}
}
但是,使用类型的嵌套成员执行相同的检查,它似乎并没有提供相同的效果。
type ChildType = 'a' | 'b';
interface BaseParent<T extends Child<ChildType>> {
child: T;
}
interface Child<T extends ChildType> {
type: T;
}
type Parent<T extends ChildType>
= T extends 'a' ? { color: 'blue' } & BaseParent<Child<'a'>>
: T extends 'b' ? { color: 'red', opacity: 2 } & BaseParent<Child<'b'>>
: never;
function test<T extends Parent<ChildType>>(parent: T) {
if (parent.child.type === 'a') {
parent.color === 'red' // should complain, but doesn't
}
}
这可以很容易地使用类型保护来纠正,但是我正在寻找一种没有它们的方法。
解决方案
首先要做的事情 - 让父数据依赖于它的子数据可能不是正确的架构。依赖关系应该下降。你可以先考虑一下。
但是,如果您愿意,我会这样做(我添加了动物示例以使我更容易理解):
type AcceptedAnimal = 'dogs' | 'cats';
interface ParentBase {
accepts: AcceptedAnimal
}
interface Cat {
meows: boolean;
}
interface Dog {
race: string;
}
type Parent = DogOwner | CatOwner;
interface DogOwner extends ParentBase {
animal: Dog
}
interface CatOwner extends ParentBase {
animal: Cat;
}
function isDogOwner(parent: ParentBase): parent is DogOwner {
return parent.accepts === 'dogs';
}
function test(parent: Parent) {
if (isDogOwner(parent)) {
parent.animal.race; // ok
return;
}
parent.animal.meows; // ok;
}
推荐阅读
- android - 在 release 中运行 detox 时没有虚拟方法 addReactInstanceEventListener
- ios - 自定义 UITableView 中的分隔符颜色不会改变
- java - Apache Ignite:选择服务器节点客户端节点将连接到
- vue-router - nuxt注销后如何重定向到主页?
- android - 如何更改 Android App Bundle 名称 (app.aab) 以反映 App 版本和构建类型
- stata - 用移动时间窗计算运行总和
- javascript - 使用 KeyUp,如何在回车键释放后获取值?
- c# - 在 iis 中托管时无法打开 excel 文件
- android - 如何使用 WorkManager 将新工作链接到已排队的工作?
- r - do.call 在 rlang 的 tidy 评估之前强制参数评估