Я хочу использовать не тупой макет для CSS-модулей, а реальные типы, поэтому я использую плагин webpack typings-for-css-modules-loader
для простого css
.foo { color: red; } .bar { color: green; }
он может генерировать example.css.d.ts объявление
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
Хорошая практика - требовать только то, что вам нужно от интерфейса, а не больше.Похоже, что bar не должно быть в ILocals и foo не должно быть в IExampleCss
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>.
ReturnType<myFunction>