gpt4 book ai didi

css - 如何在 typescript 中为 css 样式创建递归对象类型?

转载 作者:太空宇宙 更新时间:2023-11-04 00:50:21 27 4
gpt4 key购买 nike

我正在使用 React.CSSProperties 创建 css 变量,这样我就可以像这样创建

let css: React.CSSProperties = {
position: "relative",
display: "inline-block",
background: "red"
}

我正在尝试创建一个主题,该主题将在根级别具有 css 变量或嵌套在修饰符中,例如 size(sm,md,lg) 或 variant(light,dark) 或其他如下所示

let theme: MyTheme = {
background: "red", // css
color: "white", // css

button: { // custom: component name Level1
background: "red", // css
color: "white", // css

light: { // custom: modifier variant Level2
background: "red", // css
color: "white", // css

hollow: { // custom: modifier Level3
borderColor: "red",
color: "red",
background: "transparent",
}
}
dark: {
background: "red",
color: "white",

hollow: {
borderColor: "black",
color: "black",
background: "transparent",

modfierLevel4: {
some: "css"

modfierLevel5: {
some: "css"

modfierLevel6: {
some: "css"
}
}
}
}
}
}
}

基本上我是在像下面这样的 typescript 中寻找递归对象类型,但最终以循环引用结束?

type Modifiers = 'button' | 'dark' | 'light' | 'otherModifiers'

interface Theme extends React.CSSProperties {
[k in Modifiers]?: Theme;
}

我能够找到接近它的答案(下方)。

type Theme = React.CSSProperties & { [keys in Modifiers]?: Theme }

但面临一些问题。如果给定修饰符名称无效,例如“btn”而不是“button”

  • 错误在级别 1 正确抛出(如预期)
  • 但是从 2 级及更高级别不会抛出任何错误。 (但预计会抛出错误)

我应该如何为上述内容创建类型?

最佳答案

假设您使用的是 TS3.4 或以下版本:

这是 known issue 的结果其中excess property checks不对嵌套交叉类型执行,如 Theme .从技术上讲,TypeScript 中的类型通常是“开放的”或“可扩展的”,这意味着类型的值可以拥有比其类型定义中提到的更多的属性。你依赖于类似 interface A { a: string } 的东西和 interface B extends A { b: string } ,其中类型为 B 的值也是 A 类型的值.

但通常当人们像您一样使用对象文字时,添加额外属性是错误的……尤其是在您的情况下,“额外”属性只是可选属性的打印错误。所以编译器决定当你为一个类型分配一个新的对象字面量时,额外的属性是一个错误。也就是说,新对象字面量的类型是“封闭的”或“exact”……

...好吧,或者他们应该是,除了这个带有嵌套交叉点的错误。在 TypeScript 3.4 或更低版本中,这是行为:

type Foo = { baseProp: string, recursiveProp?: Foo };
const foo: Foo = {
baseProp: "a",
recursiveProp: {
baseProp: "b",
extraProp: "error as expected" // error 👍
}
}

type Bar = { baseProp: string } & { recursiveProp?: Bar };
const bar: Bar = {
baseProp: "a",
recursiveProp: {
baseProp: "b",
extraProp: "no error?!" // no error in TS3.4 😕
}
}

Playground link

幸运的是,这个错误是fixed对于 TypeScript 3.5,应该是 released在 2019 年 5 月 30 日,或者您可以通过 typescript@next 尝试每晚构建的 TypeScript

如果您等不及或不能尽快升级,您可以通过使用映射类型将交集替换为外观更正常的对象来解决此问题:

type Id<T> = { [K in keyof T]: T[K] };
type Bar = Id<{ baseProp: string } & { recursiveProp?: Bar }>;
const bar: Bar = {
baseProp: "a",
recursiveProp: {
baseProp: "b",
recursiveProp: {
baseProp: "c",
extraProp: "error yay" 👍
}
}
}

Playground link

出现了预期的错误,一切正常。希望有所帮助;祝你好运!

关于css - 如何在 typescript 中为 css 样式创建递归对象类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56062709/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com