Типы Typescript и CSS-модулей - PullRequest
       2

Типы Typescript и CSS-модулей

0 голосов
/ 29 сентября 2018

Я хочу использовать не тупой макет для CSS-модулей, а реальные типы, поэтому я использую плагин 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 знает, что это локальные пользователи. foo и css. bar members

Я пытаюсь написать функцию, которая может получить любые определения 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'.

Что не так?

Я написал соответствующий пример на %20returnObject%0D%0A%7D%0D%0A%0D%0A%0D%0A%0D%0A%2F%2F%20usage%20with%20certain%20realisation%0D%0Aexport%20interface%20ILocals%20%7B%0D%0A%20%20'foo'%3A%20string%3B%0D%0A%20%20'bar'%3A%20string%3B%0D%0A%7D%0D%0Aexport%20interface%20IExampleCss%20%7B%0D%0A%20%20locals%3A%20ILocals%3B%0D%0A%20%20'foo'%3A%20string%3B%0D%0A%20%20'bar'%3A%20string%3B%0D%0A%7D%0D%0A%0D%0Aconst%20myFunction%20%3D%20(css%3A%20IExampleCss)%3A%20returnObject%20%3D>%20%7B%0D%0A%20%20%20%20return%20%7B%0D%0A%20%20%20%20%20%20%20%20a%3A%20css.locals.foo%2C%0D%0A%20%20%20%20%20%20%20%20b%3A%20css.bar%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Aconst%20MyRenderer%3A%20ISomeInterface%20%3D%20%7B%0D%0A%20%20%20%20renderComponent%3A%20myFunction%0D%0A%7D%3B" rel="nofollow noreferrer"> машинописной площадке

// 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

1 Ответ

0 голосов
/ 01 октября 2018

Хорошая практика - требовать только то, что вам нужно от интерфейса, а не больше.Похоже, что 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
    }
}

Sidenote: для простых случаев вам не нужно объявлять тип возвращаемого значения - оно будетбыть выведен.И если вам нужен тип возвращаемого значения функции, вы можете использовать ReturnType<myFunction>.

...