Стилизованные компоненты TypeScript - PullRequest
3 голосов
/ 13 июня 2019

Используя styled-components, с обычным React.js я могу сделать так:

const Container = styled.div({
  userSelect: `none !important`,
})

однако с TypeScript я получаю ошибку:

Argument of type '{ userSelect: string; }' is not assignable to parameter of type 'TemplateStringsArray'.
  Object literal may only specify known properties, and 'userSelect' does not exist in type 'TemplateStringsArray'.ts(2345)

Какой лучший способ это исправить?

Я не хочу использовать шаблонный подход styled.div, так как я считаю его менее гибким.

Например, с шаблонными строками мы не можем делать такие вещи, как:

const flex = {
  flex: display: flex,
  col: flexDirection: `column`
}

const FlexRow = styled.div({
  ...flex.flex,
})

const FlexCol = styled.div({
   ...flex.flex,
   ...flex.col,
})

Ответы [ 2 ]

5 голосов
/ 13 июня 2019

Обновление: При дальнейшем расследовании выясняется, что @Vincent был на правильном пути, прежде чем я выяснил, что на самом деле происходит.

import styled, { CSSObject } from "styled-components";

const Container = styled.div({
  userSelect: "none !important"
} as CSSObject);

Сгенерирует следующую ошибку:

Conversion of type '{ userSelect: "none !important"; }' to type 'CSSObject' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Type '{ userSelect: "none !important"; }' is not comparable to type 'Properties<string | number>'.
    Types of property 'userSelect' are incompatible.
      Type '"none !important"' is not comparable to type '"contain" | "all" | "-moz-initial" | "inherit" | "initial" | "revert" | "unset" | "auto" | "none" | "text" | "-moz-none" | "element" | undefined'.ts(2352)

Итак, стилизованные компоненты действительно поддерживают этот синтаксис даже в TypeScript, просто не понимают суффикс !important.Вот немного измененное решение, которое вы могли бы предпочесть:

const important = <T extends string>(s: T): T => `${s} !important` as T;

const Container = styled.div({
  userSelect: important("none"),
});

Это немного странно (приведение "none !important" к "none", когда это явно не так), но оно сохраняет ваши стилизованные CSS-реквизиты чистыми и пропускаетпроверки типов.


Оригинальный ответ: Я не знаком с этим синтаксисом для стилизованных компонентов (он немного похож на JSS, но не совсем).

Я бы рекомендовал использовать стандартный синтаксис.Стилизованные компоненты обычно пишутся так:

const Container = styled.div`
  user-select: none !important;
`;
4 голосов
/ 13 июня 2019

он не распознает !important, поэтому просто приведите его к любой тихой машинописи.

styled.div({
  userSelect: 'none !important'  as any
});

EDIT - объяснение, почему это работает

, это очень просто.если вы используете атом типа ide, вы можете перейти к типу для свойства userSelect.Тип UserSelectProperty, и его значение должно быть одним из них.

export type Globals = "-moz-initial" | "inherit" | "initial" | "revert" | "unset";
export type UserSelectProperty = Globals | "-moz-none" | "all" | "auto" | "contain" | "element" | "none" | "text";

Поскольку none !important не вариант, вы должны привести его к любому.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...