[英]use conditional type in typescript interface key iteration
Hi have 2 interfaces and a type 嗨,有2个接口和一个类型
interface A { k1: string k2: string }
interface B { k3: string k4: A }
type Error = { key:string, value:string}
I have developed a declaration that creates an interface with all the keys of a given interface and the type = Error[] 我已经开发了一个声明,该声明使用给定接口的所有键和类型= Error []创建一个接口
type AutoErrors<P> = { [K in keyof P]-?: Error[] }
That works well since AutoErrors<A>
gives { k1: Error[] k2: Error[] }
由于
AutoErrors<A>
给出{ k1: Error[] k2: Error[] }
效果很好
But now I would like it to be recursive, ie , if the parameter type key is not of type string I would like its type to be AutoErrors<T>
但是现在我希望它是递归的,即,如果参数类型键不是字符串类型,我希望它的类型是
AutoErrors<T>
For example AutoErrors<B>
should be { k3: Error[], k4: AutoErrors<A> }
例如,
AutoErrors<B>
应该为{ k3: Error[], k4: AutoErrors<A> }
I have tried 我努力了
type AutoErrors<X> = { [K in keyof X]-?: X[K] extends string ? Error[] : AutoErrors<X[K]> }
type AutoErrors<X> = { [K in keyof X]-?: X[K] extends string ? Error[] : AutoErrors<X[K]> }
but it is not working well , as if the test X[K] extends string is not well interpreted type AutoErrors<X> = { [K in keyof X]-?: X[K] extends string ? Error[] : AutoErrors<X[K]> }
但是它不能很好地工作,好像测试X [K]扩展字符串不能很好地解释
You can use an approach similar to the one for DeepReadOnly 您可以使用与DeepReadOnly类似的方法
export type primitive = string | number | boolean | undefined | null
export type DeepError<T> =
T extends (infer U)[] ? Array<DeepErrorObject<U>> :
T extends primitive ? Error[] : DeepErrorObject<T>;
export type DeepErrorObject<T> = {
readonly [P in keyof T]: DeepError<T[P]>
}
// sample usage
interface A {
k1: string
k2: string
}
interface B {
k3: string
k4: A
k4Arr: B[]
}
type Error = {
key:string,
message:string
}
type ErrorA = DeepError<B>
let d: ErrorA;
d.k4Arr[0].k3; // Error[]
The code as posted in your question works in the Playground , so I suspected that something else was going on. 您的问题中张贴的代码在Playground中有效 ,因此我怀疑还有其他情况。 As it turns out, the issue had to do with optional properties, such as
事实证明,此问题与可选属性有关,例如
type UhOh = AutoErrors<{ a?: string }>; // becomes {a: string}, not good
The original AutoErrors<>
definition didn't work in that case, because string | undefined
原始的
AutoErrors<>
定义在这种情况下不起作用,因为string | undefined
string | undefined
does not extend string
. string | undefined
不扩展string
。 The fix for that, as you know, is to check for string | undefined
如您所知,解决此问题的方法是检查
string | undefined
string | undefined
instead of just string
: string | undefined
而不只是string
:
type AutoErrors<X> = {
[K in keyof X]-?: X[K] extends string | undefined ?
Error[] : AutoErrors<X[K]>
}
which works: 哪个工作:
type Okay = AutoErrors<{ a?: string }>; // becomes {a: Error[]}, as expected
Glad you found out what was going on. 很高兴您发现发生了什么事。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.