TypeScript 只能迭代接口的"own"键吗?



有没有任何方法可以构建一个类似DeepRequired<T>的帮助器类型,它只会影响不是"的键;外部";到T

我的意思是,使用这个示例代码:

interface Test{
prop1?: string
prop2: {
prop3?: {
prop3b?: HTMLElement
}
prop4?: number
}
}
declare const test: DeepRequired<Test>
const c: HTMLElement = test.prop2.prop3.prop3b

这将在c上失败,错误为:

类型"{accessKey:string;只读accessKeyLabel:string;autocapitalize:string;dir:string,可拖动:布尔;隐藏:布尔;innerText:string,lang:string、只读offsetHeight:number;…233 more…;focus:(options?:FocusOptions|undefined(=>void;}"不可分配给类型"HTMLElement"。

如果我理解正确的话,这是因为prop3b?: HTMLElement已经转换为prop3b: DeepRequired<HTMLElement>

有没有办法成为";"深而浅"?

我尝试过构建自己的递归类型,比如:

type IsObject<T> = T extends AnyArray
? false
: T extends object
? true
: false
type RRequired<T> = {
[P in keyof T]-?: NonNullable<T[P]> extends Builtin
? T[P]
: NonNullable<T[P]> extends AnyArray
? T[P]
: IsObject<NonNullable<T[P]>> extends true
? RRequired<T[P]>
: T[P]
}

但我找不到停止递归的方法。

我的理解是,对于TypeScript,我的Test接口相当于:

interface Test{
prop1?: string
prop2: {
prop3?: {
prop3b?: {
...HTMLElement
}
}
prop4?: number
}
}

即,在我使用HTMLElement的类型中内联的所有属性(或任何其他类型/接口(。。。所以我不知道如何区分我的接口的嵌套属性和";"外部";,非内置类型。

那么,有没有什么方法可以编写一个RRequired<T>类型,将Test转换为以下类型?

RRequired<Test> == {
prop1: string
prop2: {
prop3: {
prop3b: HTMLElement // <- preserve HTMLElement
}
prop4: number
}
}

实现这样的目标的唯一方法是对照;允许的类型";你不想让它被深深地要求。例如

type DeepRequired<T> = T extends HTMLElement ? T : {
[K in keyof T]-?: DeepRequired<T[K]>
}

type AllowedTypes = HTMLElement | WhateverTypeYouWantToAllow | ...
type DeepRequired<T> = T extends AllowedTypes ? T : {
[K in keyof T]-?: DeepRequired<T[K]>
}

但我们知道,这会检查结构是否匹配。这意味着,如果你有一个形状与HTMLElement完全相似的类型,或者你的AllowedTypes中的任何元素都是类似形状的,那么这个条件就会短路,不会给你想要的结果。这里类型Bogus类似于Test.prop2中的所有内容,这意味着prop2以下的所有内容都不需要

type Bogus = {
prop4?: number;
}
type AllowedTypes = HTMLElement | Bogus;
type DeepRequired<T> = T extends AllowedTypes ? T : {
[K in keyof T]-?: DeepRequired<T[K]>
}
declare const z: DeepRequired<Test>
z.prop2.prop3.prop3b // BOOM, prop3 is optional!

由于HTMLElement及其所有子类型都是非常复杂的形状,您很可能会使用这种方法。但在一个结构类型的系统中,形状就是一切,随之而来的是一些棘手的问题。

最新更新