打字稿和CSS模块类型

时间:2018-09-29 03:09:15

标签: typescript css-modules

我不想对CSS模块使用哑模拟,而是对真实类型使用,所以我使用了webpack插件typings-for-css-modules-loader

对于简单的CSS

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>

所以在我的代码中,我可以像这样使用它

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
                     ^^^^^^^^^^
};

和VSCode知道本地人。 foo 和CSS。 bar 成员

我尝试编写一个函数,该函数能够获取打字稿中的任何CSS定义作为输入参数

[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'.

我得到了错误:

// 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 ^^^^^^^ };

怎么了?

我已经在typescript playground

中写了一个相关示例
[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

这是错误:

OR

1 个答案:

答案 0 :(得分: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>