首页 > 解决方案 > 在打字稿界面键迭代中使用条件类型

问题描述

嗨有2个接口和一个类型

interface A {
    k1: string
    k2: string
}

interface B {
    k3: string
    k4: A
}

type Error = { key:string, value:string}

我开发了一个声明,它使用给定接口的所有键创建一个接口,并且type = Error[]

type AutoErrors<P> = { 
    [K in keyof P]-?: Error[] 
}

这很好用,因为AutoErrors<A>

{
  k1: Error[]
  k2: Error[]
}

但是现在我希望它是递归的,即如果参数类型键不是字符串类型,我希望它的类型是AutoErrors<T>

例如AutoErrors<B>应该是

{
  k3: Error[],
  k4: AutoErrors<A>
}

我努力了

type AutoErrors<X> = {
  [K in keyof X]-?: X[K] extends string ? Error[] : AutoErrors<X[K]>;
};

但它不能很好地工作,好像测试 X[K] 扩展字符串没有得到很好的解释

标签: typescript

解决方案


您问题中发布的代码在 Playground 中有效,所以我怀疑发生了其他事情。事实证明,这个问题与可选属性有关,例如

type UhOh = AutoErrors<{ a?: string }>; // becomes {a: string}, not good

在这种情况下,原始AutoErrors<>定义不起作用,因为string | undefined不扩展string. 如您所知,解决方法是检查string | undefined而不是仅检查string

type AutoErrors<X> = {
  [K in keyof X]-?: X[K] extends string | undefined ?
  Error[] : AutoErrors<X[K]>
}

哪个有效:

type Okay = AutoErrors<{ a?: string }>; // becomes {a: Error[]}, as expected

很高兴你知道发生了什么。


推荐阅读