如何在不丢失 Typescript 的任何道具的情况下键入样式化的组件?
How to type a styled component without losing any prop with Typescript?
我是样式化组件的新手,我希望能够正确输入我的样式化组件,这样当我传递 props 时 "vs code" 我可以自动检测我拥有的所有这些 props,而不仅仅是一个在主题或我可以用界面放置的主题中。
有没有像我在其他 中看到的那样不使用 HOC 的方法?是否有可能得到一个通用的道具,而不必像示例中那样在每个 属性 样式中定义?
app.theme.ts
export const theme = {
palette: {
primaryColor: '#FF5018',
secondaryColor: '#252729',
tertiaryColor: '#1A1C1E',
textColor: 'white',
},
};
export type Theme = typeof theme;
navigation-bar.styled.component.ts
export const NavigationBarStyled = styled.div`
grid-area: navigation-bar-item;
padding-left: 2rem;
display: flex;
align-items: center;
color: ${({ theme }) => theme.palette.primaryColor};
background-color: ${({ theme }) => theme.palette.primaryColor};
`;
提前致谢,
最佳
出于某种原因(可能是由于 styled-components
的打字稿定义的编写方式),如果您删除其中一层嵌套,Theme
的打字仍然有效。这个片段类型检查对我来说没有错误(v4)即打字稿知道 primaryColor
是 string
:
const theme = {
primaryColor: '#FF5018',
secondaryColor: '#252729',
tertiaryColor: '#1A1C1E',
textColor: 'white',
};
type Theme = typeof theme;
type Props = Theme & {
// ... other keys
}
const NavigationBarStyled = styled.div<Props>`
grid-area: navigation-bar-item;
padding-left: 2rem;
display: flex;
align-items: center;
color: ${props => props.primaryColor};
background-color: ${props => props.primaryColor};
`;
它可以像@Huy-Nguyen 所说的那样解决,但在实践中,您会丢失 Styled Components 的属性,或者您必须多次定义相同的属性。
所以最好的选择是 Styled-Components 网站所说的(定义主题界面):
theme.ts
export default interface ThemeInterface {
primaryColor: string;
primaryColorInverted: string;
}
styled-components.ts
import * as styledComponents from "styled-components";
import ThemeInterface from "./theme";
const {
default: styled,
css,
createGlobalStyle,
keyframes,
ThemeProvider
} = styledComponents as styledComponents.ThemedStyledComponentsModule<ThemeInterface>;
export { css, createGlobalStyle, keyframes, ThemeProvider };
export default styled;
然后,你使用那个:
import styled from 'app/styled-components';
// theme is now fully typed
const Title = styled.h1`
color: ${props => props.theme.primaryColor};
`;
只需传递 link: https://www.styled-components.com/docs/api#define-a-theme-interface
非常感谢大家。
我们采用了不同的方法。
注意:Styled Components v5 with React Native
定义您的主题类型。
// MyTheme.ts
export type MyTheme = {
colors: {
primary: string;
background: string;
};
};
在您的主题上使用该类型。
// themes.ts
export const LightTheme: MyTheme = {
colors: {
primary: 'white',
background: 'white',
},
};
export const DarkTheme: MyTheme = {
colors: {
primary: 'grey',
background: 'black',
},
};
使用 declaration merging 将 MyTheme 类型 "merge" 设置为 Styled Components 默认主题。
// styled.d.ts
import 'styled-components';
import { MyTheme } from '../src/themes/MyTheme';
declare module 'styled-components' {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface DefaultTheme extends MyTheme {}
}
好的,酷。 theme
属性输入正确。
组件本身呢?
用 StyledProps
类型包装您的特定组件属性。
import { StyledProps } from 'styled-components';
import styled from 'styled-components/native';
type MyViewProps = StyledProps<{
backgroundColor?: string;
isAlert?: boolean;
}>;
const MyView = styled.View(
(props: MyViewProps) => `
background-color: ${props.backgroundColor || props.theme.colors.background};
color: ${props.isAlert ? red : props.theme.colors.primary}
`,
);
在此示例中,props.backgroundColor
和 props.theme.colors.background
都将自动完成。当您更新 MyTheme
类型或特定组件类型时,它应该可以正常工作。
不知道是不是最好的方法。但是我找到了如下解决方法。
// theme.ts
const theme = {
colors: {
...
}
};
export type themeTypes = typeof theme;
export default theme;
// styled.d.ts ( in root folder )
import 'styled-components'
import { themeTypes } from '@/styles/theme'
declare module 'styled-components' {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface DefaultTheme extends themeTypes {}
}
我是样式化组件的新手,我希望能够正确输入我的样式化组件,这样当我传递 props 时 "vs code" 我可以自动检测我拥有的所有这些 props,而不仅仅是一个在主题或我可以用界面放置的主题中。
有没有像我在其他
app.theme.ts
export const theme = {
palette: {
primaryColor: '#FF5018',
secondaryColor: '#252729',
tertiaryColor: '#1A1C1E',
textColor: 'white',
},
};
export type Theme = typeof theme;
navigation-bar.styled.component.ts
export const NavigationBarStyled = styled.div`
grid-area: navigation-bar-item;
padding-left: 2rem;
display: flex;
align-items: center;
color: ${({ theme }) => theme.palette.primaryColor};
background-color: ${({ theme }) => theme.palette.primaryColor};
`;
提前致谢, 最佳
出于某种原因(可能是由于 styled-components
的打字稿定义的编写方式),如果您删除其中一层嵌套,Theme
的打字仍然有效。这个片段类型检查对我来说没有错误(v4)即打字稿知道 primaryColor
是 string
:
const theme = {
primaryColor: '#FF5018',
secondaryColor: '#252729',
tertiaryColor: '#1A1C1E',
textColor: 'white',
};
type Theme = typeof theme;
type Props = Theme & {
// ... other keys
}
const NavigationBarStyled = styled.div<Props>`
grid-area: navigation-bar-item;
padding-left: 2rem;
display: flex;
align-items: center;
color: ${props => props.primaryColor};
background-color: ${props => props.primaryColor};
`;
它可以像@Huy-Nguyen 所说的那样解决,但在实践中,您会丢失 Styled Components 的属性,或者您必须多次定义相同的属性。
所以最好的选择是 Styled-Components 网站所说的(定义主题界面):
theme.ts
export default interface ThemeInterface {
primaryColor: string;
primaryColorInverted: string;
}
styled-components.ts
import * as styledComponents from "styled-components";
import ThemeInterface from "./theme";
const {
default: styled,
css,
createGlobalStyle,
keyframes,
ThemeProvider
} = styledComponents as styledComponents.ThemedStyledComponentsModule<ThemeInterface>;
export { css, createGlobalStyle, keyframes, ThemeProvider };
export default styled;
然后,你使用那个:
import styled from 'app/styled-components';
// theme is now fully typed
const Title = styled.h1`
color: ${props => props.theme.primaryColor};
`;
只需传递 link: https://www.styled-components.com/docs/api#define-a-theme-interface
非常感谢大家。
我们采用了不同的方法。
注意:Styled Components v5 with React Native
定义您的主题类型。
// MyTheme.ts export type MyTheme = { colors: { primary: string; background: string; }; };
在您的主题上使用该类型。
// themes.ts export const LightTheme: MyTheme = { colors: { primary: 'white', background: 'white', }, }; export const DarkTheme: MyTheme = { colors: { primary: 'grey', background: 'black', }, };
使用 declaration merging 将 MyTheme 类型 "merge" 设置为 Styled Components 默认主题。
// styled.d.ts import 'styled-components'; import { MyTheme } from '../src/themes/MyTheme'; declare module 'styled-components' { // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface DefaultTheme extends MyTheme {} }
好的,酷。 theme
属性输入正确。
组件本身呢?
用
StyledProps
类型包装您的特定组件属性。import { StyledProps } from 'styled-components'; import styled from 'styled-components/native'; type MyViewProps = StyledProps<{ backgroundColor?: string; isAlert?: boolean; }>; const MyView = styled.View( (props: MyViewProps) => ` background-color: ${props.backgroundColor || props.theme.colors.background}; color: ${props.isAlert ? red : props.theme.colors.primary} `, );
在此示例中,props.backgroundColor
和 props.theme.colors.background
都将自动完成。当您更新 MyTheme
类型或特定组件类型时,它应该可以正常工作。
不知道是不是最好的方法。但是我找到了如下解决方法。
// theme.ts
const theme = {
colors: {
...
}
};
export type themeTypes = typeof theme;
export default theme;
// styled.d.ts ( in root folder )
import 'styled-components'
import { themeTypes } from '@/styles/theme'
declare module 'styled-components' {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface DefaultTheme extends themeTypes {}
}