如何通过 Typescript 使用 TailwindCSS 的解析配置

问题描述 投票:0回答:4

我将以下代码导入到我的 .tsx 组件中:

import resolveConfig from 'tailwindcss/resolveConfig';
import tailwindConfig from '../../../tailwind.config.js';

const fullConfig = resolveConfig(tailwindConfig)

如果我随后引用

fullConfig.theme.colors["blue"]["700"]
,我会收到一条错误消息:

Element 隐式具有“any”类型,因为“blue”类型的表达式不能用于索引类型“TailwindThemeColors”。 “TailwindThemeColors”类型上不存在属性“blue”。

颜色的 Tailwind 类型定义是:

export type TailwindColorValue = string | TailwindColorGroup | TailwindColorFunction;

export interface TailwindValuesColor {
    readonly [key: string]: TailwindColorValue;
}

由于类型没有明确表示

"blue"
是一个值并且它可能是一个对象,所以这就是错误的原因(我认为)。

我遇到的另一个问题是我的

tsconfig.json
中出现错误,因为我正在导入 JS 文件。 添加
"exclude": ["tailwind.config.js"]
并不能解决问题。

我很确定这是一个 Typescript 问题,而不是 Tailwind 问题......

我的问题是:

  1. 如何让 Typescript 知道顺风主题中颜色的
    "blue"
    属性,以及
  2. 如何阻止导入 JS 配置时出现 tsconfig 错误?
reactjs typescript tailwind-css tsx
4个回答
5
投票

回答原来的问题#1。
不知何故,这样做时,打字稿无法为您提供正确的打字:

import tailwindConfig from 'tailwind-config'
// or so:
import * as tailwindConfig from 'tailwind-config'

所以我想,我实际上只需要

theme
(而
content
只是
Config
类型中所需要的),结果是这样的:

import { content, theme } from 'tailwind-config'; // just an alias for the tailwind.config.js
import resolveConfig from 'tailwindcss/resolveConfig';

const fullConfig = resolveConfig({
  content,
  theme,
});

const foo = fullConfig.theme.colors['black-1']; // foo: string;

这里唯一的问题是我不能在配置文件本身中包含

/** @type {import('tailwindcss').Config} */
,因为 IDE 开始从那里解析类型而不是配置对象。但这主要是 IDE 问题,也可能可以解决。


对于问题#2,我相信在

"allowJs": true
compilerOptions
中添加
tsconfig.json
就能解决问题。


4
投票

这看起来是由于 Tailwind 输入其

resolveConfig
返回值所使用的联合类型而出现的问题。本质上,由于联合,TS 不知道
fullConfig.theme.colors
的值是对象还是 getter 函数(同样,
fullConfig.theme.colors["blue"]
是字符串、颜色组对象还是颜色函数) - 大概是这样是因为这个决定留给用户的 tailwind.conf 实现选择,而 Tailwind 不会推断它。

解决此问题的最简单方法可能是编写自己的函数,该函数采用您尝试使用的联合类型值并仅返回您想要的特定类型,例如。

import _ from 'lodash';

const asColorObject = (
  input: TailwindThemeColors | undefined,
): Exclude<typeof input, Function | undefined> => {
  if (_.isFunction(input) || !input) throw new Error();
  return input;
};

const fullConfig = resolveConfig(tailwindConfig);
const colorBlue = asColorObject(fullConfig.theme.colors)['blue'];

关于导入 Tailwind 配置时出现错误的原因,请检查 TSConfig 中

allowJs
中的
checkJS
compilerOptions
键。否则,如果您使用的是 Create React App,则根本不可能采用这种方式,因为您无法从
src
文件夹外部导入文件。


0
投票

我想也许你可以使用顺风默认配置类型来解决这样的问题:

import resolveConfig from 'tailwindcss/resolveConfig'
import tailwindConfig from 'tailwind.config'
import { TailwindConfigDefault } from 'tailwindcss/tailwind-config-default'
import { TailwindConfig } from 'tailwindcss/tailwind-config'

export default resolveConfig(tailwindConfig as TailwindConfig) as TailwindConfigDefault & {
  theme: {
    colors: {
      main: {
        light: 'var(--color-main-light)'
        dark: 'var(--color-main-dark)'
      }
    }
  }
  // other custom config
}

0
投票

这是我的看法,重点关注非生产组件,只是为了与设计师分享正在使用的调色板:

/* the actual referencing */
import resolveConfig from 'tailwindcss/resolveConfig'
import tailwindConfig from '@/tailwind.config.js'

(...)
/* within component */
const config = resolveConfig(tailwindConfig);
(...)
{
    (((config.theme.colors as any).status as string[])).map((v, idx) => 
    <View key={idx}>
        <ColorReference colorLegend={v} />
    </View>
    )
}
/* tailwind.config.js */
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./app/**/*.{js,jsx,ts,tsx}",
    "./components/**/*.{js,jsx,ts,tsx}"
  ],
  presets: [require("nativewind/preset")],
  theme: {
    screens: {
      'small': { max: '768px' },
      'medium': { min: '769px', max: '1200px' },
      'large': { min: '1201px' },
    },
    extend: {
      keyframes: {
        loading: {
          '0%': { transform: 'rotate(0.0deg)' },
          '50%': { transform: 'rotate(180.0deg)' },
          '100%': { transform: 'rotate(360.0deg)' },
        },
      },
      animation: {
        'loading-spin': 'loading 2.5s linear infinite',
      },
      colors: {
        "grayneutral-4": "var(--grayneutral-4)",
        "grayneutral-5": "var(--grayneutral-5)",
        "green-02": "var(--green-02)",
        "green-03": "var(--green-03)",
        white: "var(--white)",
        "titletext": "#0369a1",
        "principal": "#005E66",
        "variant": [ "#2C8990", "#3EBBC6", "#B1ECF1", "#E9FAFB", "#F1FEFF" ],
        "tonscinza": [ "#212529", "#3B3B3B", "#5D6369", "#6C757D", "#777777", "#9C9C9C", "#DDDDDD", "#E5E5E5", "#F4F4F4", "#F6F6F6", "#FFFFFF" ],
        "tags": [ "#E6DEED", "#D6E4EE", "#F1E1E9", "#ECE0DB", "#FAE3DE", "#DEECDC", "#FAEDCC" ],
        "status": [ "#E76969", "#F4B14D", "#629B7B" ],
      },
      fontFamily: {
        "desktop-desktop-h1": "var(--desktop-desktop-h1-font-family)",
        "desktop-heading-display-h3": "var(--desktop-heading-display-h3-font-family)",
        "roboto": "'Roboto_400Regular'",
        "roboto-regular": "'Roboto_400Regular'",
        "roboto-light": "'Roboto_300Light'",
        "roboto-bold": "'Roboto_700Bold'",
      },
    },
  },
  plugins: [],
}
© www.soinside.com 2019 - 2024. All rights reserved.