尝试添加自定义 属性 时使用 emotion/styled 在打字稿中收到错误
Receiving an error in typescript using emotion/styled when trying to add a custom property
这是我要实现的代码行。
const MaybeBigHeading = styled(Heading)( ({ big:boolean = false }) => [ big && tw`text-4xl` ]);
我收到的错误是:
Property 'big' does not exist on type 'ClassAttributes<HTMLHeadingElement> & HTMLAttributes<HTMLHeadingElement> & { theme?: Theme | undefined; } & { ...; }'.ts(2339)
这个错误对我来说有点意义,但我正在学习 ReactJS/Typescript 并且正在尝试从 Javascript 教程中实现一些东西;这适用于 Javascript,但不适用于 Typescript。
不确定如何在 Typescript 中解决这个问题。
发布后不久就找到了解决方案
通过添加
declare module "react" {
interface HTMLAttributes<T> extends DOMAttributes<T> {
big?: boolean;
}
}
到 .tsx 文件,我能够使用“大”作为新组件的属性
完整 App.tsx 个文件如下
/** @jsxImportSource @emotion/react */
import tw from "twin.macro";
import { DOMAttributes } from "react";
import styled from "@emotion/styled";
const Heading= tw.h1`text-blue-500 text-2xl p-2`;
const BigHeading = tw(Heading)`text-4xl`;
declare module "react" {
interface HTMLAttributes<T> extends DOMAttributes<T> {
big?: boolean;
}
}
const MaybeBigHeading = styled(Heading)( ({ big = false }) => [ big && tw`text-4xl text-red-300` ]);
const Container = tw.div`max-w-4xl mx-auto p-5 mt-5`;
function App() {
return (
<Container >
<BigHeading>Hello World</BigHeading>
<Heading>This is an example</Heading>
<MaybeBigHeading>This might be a Big Heading</MaybeBigHeading>
<MaybeBigHeading big>This IS a Big Heading</MaybeBigHeading>
</Container>
);
}
export default App;
styled
函数的类型称为 generic。泛型允许您通过参数传递自己的类型。通用参数放在尖括号 (<>
) 之间。在你的情况下,你会像这样使用它:
const MaybeBigHeading = styled(Heading)<{ big?: boolean; }>(({ big = false }) => [ big && tw`text-4xl text-red-300` ]);
请参阅有关使用 TypeScript with Emotion too. You can see how the generic type for styled
is defined here 的文档。
关于您发现的解决方案的注释
在您发现的解决方案中,您通过为 big
添加自己的类型扩展了 HTMLAttributes
接口:
declare module "react" {
interface HTMLAttributes<T> extends DOMAttributes<T> {
big?: boolean;
}
}
是的,这行得通,但在没有其他选择的情况下,它本质上是一种蛮力方法。这不是一个好主意,因为它污染了 HTML 属性的含义,并且可能会使您代码的未来读者(可能是您自己)感到困惑。 big
不是 HTML 属性,因此不应存在于 HTML 属性界面上。
这是我要实现的代码行。
const MaybeBigHeading = styled(Heading)( ({ big:boolean = false }) => [ big && tw`text-4xl` ]);
我收到的错误是:
Property 'big' does not exist on type 'ClassAttributes<HTMLHeadingElement> & HTMLAttributes<HTMLHeadingElement> & { theme?: Theme | undefined; } & { ...; }'.ts(2339)
这个错误对我来说有点意义,但我正在学习 ReactJS/Typescript 并且正在尝试从 Javascript 教程中实现一些东西;这适用于 Javascript,但不适用于 Typescript。
不确定如何在 Typescript 中解决这个问题。
发布后不久就找到了解决方案
通过添加
declare module "react" {
interface HTMLAttributes<T> extends DOMAttributes<T> {
big?: boolean;
}
}
到 .tsx 文件,我能够使用“大”作为新组件的属性
完整 App.tsx 个文件如下
/** @jsxImportSource @emotion/react */
import tw from "twin.macro";
import { DOMAttributes } from "react";
import styled from "@emotion/styled";
const Heading= tw.h1`text-blue-500 text-2xl p-2`;
const BigHeading = tw(Heading)`text-4xl`;
declare module "react" {
interface HTMLAttributes<T> extends DOMAttributes<T> {
big?: boolean;
}
}
const MaybeBigHeading = styled(Heading)( ({ big = false }) => [ big && tw`text-4xl text-red-300` ]);
const Container = tw.div`max-w-4xl mx-auto p-5 mt-5`;
function App() {
return (
<Container >
<BigHeading>Hello World</BigHeading>
<Heading>This is an example</Heading>
<MaybeBigHeading>This might be a Big Heading</MaybeBigHeading>
<MaybeBigHeading big>This IS a Big Heading</MaybeBigHeading>
</Container>
);
}
export default App;
styled
函数的类型称为 generic。泛型允许您通过参数传递自己的类型。通用参数放在尖括号 (<>
) 之间。在你的情况下,你会像这样使用它:
const MaybeBigHeading = styled(Heading)<{ big?: boolean; }>(({ big = false }) => [ big && tw`text-4xl text-red-300` ]);
请参阅有关使用 TypeScript with Emotion too. You can see how the generic type for styled
is defined here 的文档。
关于您发现的解决方案的注释
在您发现的解决方案中,您通过为 big
添加自己的类型扩展了 HTMLAttributes
接口:
declare module "react" {
interface HTMLAttributes<T> extends DOMAttributes<T> {
big?: boolean;
}
}
是的,这行得通,但在没有其他选择的情况下,它本质上是一种蛮力方法。这不是一个好主意,因为它污染了 HTML 属性的含义,并且可能会使您代码的未来读者(可能是您自己)感到困惑。 big
不是 HTML 属性,因此不应存在于 HTML 属性界面上。