为什么嵌套模板字面量内的theme会触发TypeScript类型报错?
报错原因
首先明确:该报错确实是由theme处于嵌套模板字面量中导致的。
外层styled.div模板字符串内的插值函数,会被styled-components自动关联注入的Theme类型,TypeScript可以正常推导出theme的类型。但你自定义的media.min.medium模板字面量函数没有默认关联styled-components的Theme类型,TS无法自动推导嵌套在其内部的插值函数入参theme的类型,因此抛出隐式any的报错。
解决方案
方案1:手动给theme加类型注解(最简便)
直接给嵌套插值中的theme参数声明你已定义的Theme类型即可,如果你已经全局扩展了styled-components的DefaultTheme,可以直接导入使用:
import { DefaultTheme } from 'styled-components'; export const HeaderNavInner = styled.div` padding: ${({ theme }) => theme.spacing.generic[4]}px ${({ theme }) => theme.spacing.generic[6]}px; ${media.min.medium` padding: ${({ theme }: { theme: DefaultTheme }) => theme.spacing.generic[4]}px 0; `} `;
方案2:给media工具函数添加泛型支持(一劳永逸)
在定义media响应式工具时,关联styled-components的ThemedCssFunction类型,让其内部插值自动继承Theme类型,示例定义如下:
import { DefaultTheme, ThemedCssFunction, css } from 'styled-components'; // 你的断点配置 const breakpoints = { medium: 768, small: 576, large: 1200 } as const; type Breakpoint = keyof typeof breakpoints; export const media = { min: (Object.keys(breakpoints) as Breakpoint[]).reduce((acc, bp) => { acc[bp] = (strings: TemplateStringsArray, ...interpolations: Parameters<ThemedCssFunction<DefaultTheme>>) => css` @media (min-width: ${breakpoints[bp]}px) { ${css(strings, ...interpolations)} } ` as ThemedCssFunction<DefaultTheme>; return acc; }, {} as Record<Breakpoint, ThemedCssFunction<DefaultTheme>>) };
按上述方式定义后,所有media方法内的插值函数都可以自动识别theme类型,不需要手动加注解。
方案3:确认全局Theme类型扩展生效
如果你已经做了styled-components的全局类型扩展,需要确认声明文件(一般命名为styled-components.d.ts放在项目根目录或src目录下)配置正确,示例如下:
import 'styled-components'; declare module 'styled-components' { export interface DefaultTheme { spacing: { generic: number[]; // 补充你theme中其他属性的类型 }; // 补充你theme中其他顶层属性的类型 } }
该声明需要和你实际传入ThemeProvider的theme结构完全对应,才可以正常推导类型。
内容的提问来源于stack exchange,提问作者brendangibson
相关产品推荐
相关产品推荐

