带索引器的Typescript递归类型

Aar*_*sen 5 recursion typescript

我想像这样定义一个递归的类型,基本上:

interface CSSProperties {
  marginLeft?: string | number
  [key: string]?: CSSProperties
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,打字稿文档说:

虽然字符串索引签名是描述"字典"模式的有效方式,但它们还强制所有属性都与其返回类型匹配.这是因为字符串索引声明obj.property也可用作obj ["property"].在以下示例中,name的类型与字符串索引的类型不匹配,type-checker给出错误:

这似乎说这不可能用打字稿来表达,这似乎是一个严重的限制.Flow做了我认为正确的事情,并假设marginLeft不属于索引规范.

这在TypeScript中是否可行?或者,有没有办法指定字符串是任何字符串,一组字符串?那样的话,我可以大致做一些事情:

interface NestedCSSProperties: CSSProperties {
  [P not in keyof CSSProperties]?: CSSProperties
}
Run Code Online (Sandbox Code Playgroud)

Ore*_*ari 1

在这种情况下,您必须包含字符串和数字。然后您可以定义您的覆盖。使用此示例,如果您尝试将地图分配给“marginLeft”,TS 会抱怨,但会允许其他一切。

如果有更多限制,您可能需要编写一个可能使用映射类型的更深入的 .d.ts 文件。

您可以使用像 Pick 这样的预设映射类型来简化您的专有属性,但我承认,有时我很难将我的大脑集中在它们上。

interface IMap<T> {
    [key: string]: T
}

type CSSPropertyValue = string | number | CSSPropertiesBase;

interface CSSPropertiesBase extends IMap<CSSPropertyValue>
{

}

interface CSSProperties extends CSSPropertiesBase
{
    marginLeft?: string|number;
}
Run Code Online (Sandbox Code Playgroud)