Typescript 和 CSS 模块类型
Posted
技术标签:
【中文标题】Typescript 和 CSS 模块类型【英文标题】:Typescript and CSS-modules types 【发布时间】:2019-03-05 00:10:12 【问题描述】:我不想对 CSS 模块使用愚蠢的 mock,而是使用真正的类型,所以我使用 webpack 插件typings-for-css-modules-loader
对于简单的 css
.foo color: red;
.bar color: green;
可以生成example.css.d.ts
声明
export interface ILocals
'foo': string;
'bar': string;
export interface IExampleCss
locals: ILocals;
'foo': string;
'bar': string;
declare const styles: IExampleCss
export default styles;
所以在我的代码中我可以像这样使用它
import css from './example.css';
const locals = css;
<div className=locals.foo>Red</div>
<div className=css.bar>Green</div>
而且 VSCode 知道 locals.foo 和 css.bar 成员
我尝试编写一个函数,它能够在 typescript 中获取任何 css 定义作为输入参数
interface IStringHash
[key: string]: string;
interface ICSSLocals
locals: IStringHash;
[key: string]: string | IStringHash;
interface ISomeInterface
renderComponent: (css: ICSSLocals): React.ReactNode
const myFunction = (css: IExampleCss) =>
return (
<div key="1" className=css.locals.foo>Red</div>
<div key="2" className=css.bar>Green</div>
)
const MyRenderer: ISomeInterface =
renderComponent: myFunction
^^^^^^^^^^
;
我得到错误:
[ts]
Type 'IExampleCss' is not assignable to type 'ICSSLocals'.
Type 'IExampleCss' is not assignable to type 'ICSSLocals'.
Types of property 'locals' are incompatible.
Type 'ILocals' is not assignable to type 'IStringHash'.
Index signature is missing in type 'ILocals'.
怎么了?
我在typescript playground写了一个相关的示例
// Declaration with generics
interface IStringHash
[key: string]: string;
interface ICSSModule
locals: IStringHash;
[key: string]: string | IStringHash;
interface returnObject
a: string,
b: string
interface ISomeInterface
renderComponent: (css: ICSSModule) => returnObject
// usage with certain realisation
export interface ILocals
'foo': string;
'bar': string;
export interface IExampleCss
locals: ILocals;
'foo': string;
'bar': string;
const myFunction = (css: IExampleCss): returnObject =>
return
a: css.locals.foo,
b: css.bar
const MyRenderer: ISomeInterface =
renderComponent: myFunction
^^^^^^^
;
这是错误:
[ts]
Type '(css: IExampleCss) => returnObject' is not assignable to type '(css: ICSSModule) => returnObject'.
Types of parameters 'css' and 'css' are incompatible.
Type 'ICSSModule' is not assignable to type 'IExampleCss'.
Property ''foo'' is missing in type 'ICSSModule'.
(property) ISomeInterface.renderComponent: (css: ICSSModule) => returnObject
【问题讨论】:
您能否提供更多信息,您在使用myFunction
做什么?采用“任何 CSS 声明”似乎并不比仅使用 any
类型好多少。
@Ski 我已经修复了上面的功能
@Ski 我需要类型建议,如果有显示错误
我很困惑:如果myFunction
访问css.locals.foo
和css.bar
,那么它只适用于类名为foo
和bar
的CSS 模块。那么,你为什么要声明 myFunction
采用任何 CSS 模块?
@MattMcCutchen 我为服务器和浏览器的使用风格使用了一些加载器——所以它并不那么重要
【参考方案1】:
好的做法是只需要你需要的界面而不是更多。所以看起来bar
不应该在ILocals
和foo
不应该在IExampleCss
export interface ILocals
'foo': string;
// 'bar': string; <--
export interface IExampleCss
locals: ILocals;
// 'foo': string; <--
'bar': string;
const myFunction = (css: IExampleCss): returnObject =>
return
a: css.locals.foo,
b: css.bar
旁注:对于简单的情况,您不必声明返回类型——它会被推断出来。而如果需要函数返回值的类型,可以使用ReturnType<myFunction>
。
【讨论】:
css.locals.foo
用于示例显示任何项目都可以直接访问或通过locals
访问
抱歉搞混了,foo
应该留下,bar
应该离开以上是关于Typescript 和 CSS 模块类型的主要内容,如果未能解决你的问题,请参考以下文章
将 sass/css 模块添加到 typescript react app
Create-react-app + TypeScript + CSS 模块:自动生成类型定义而不从 CRA 中弹出
如何手动补充陈年老库(或纯 JS 代码)的 TypeScript 类型?