【发布时间】:2021-03-09 18:34:03
【问题描述】:
有什么方法可以构建一个类似于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:字符串;只读 accessKeyLabel: string;自动大写:字符串;目录:字符串;可拖动:布尔值;隐藏:布尔值;内部文本:字符串;语言:字符串;只读 offsetHeight: number; ... 233 更多 ...;焦点:(选项?: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
}
}
【问题讨论】:
标签: typescript typescript-generics