简体   繁体   English

如何使用 TailwindCSS 的解析配置 Typescript

[英]How to use TailwindCSS's resolve config with Typescript

I'm importing the following code into my.tsx component:我正在将以下代码导入 my.tsx 组件:

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

const fullConfig = resolveConfig(tailwindConfig)

If I then reference fullConfig.theme.colors["blue"]["700"] I get an error saying:如果我然后引用fullConfig.theme.colors["blue"]["700"]我收到一条错误消息:

Element implicitly has an 'any' type because expression of type '"blue"' can't be used to index type 'TailwindThemeColors'.元素隐式具有“任何”类型,因为“蓝色”类型的表达式不能用于索引类型“TailwindThemeColors”。 Property 'blue' does not exist on type 'TailwindThemeColors'. “TailwindThemeColors”类型上不存在属性“blue”。

The Tailwind type definition for colors is: colors 的 Tailwind 类型定义是:

export type TailwindColorValue = string | TailwindColorGroup | TailwindColorFunction;

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

Since the type does not explicitly say that "blue" is a value and that it could be an object, that's the cause of the error (I think).由于类型没有明确说明"blue"是一个值,它可能是 object,这就是错误的原因(我认为)。

An additional problem I'm getting is an error in my tsconfig.json , because I'm importing a JS file.我遇到的另一个问题是tsconfig.json中的错误,因为我正在导入 JS 文件。 Adding "exclude": ["tailwind.config.js"] doesn't solve the issue.添加"exclude": ["tailwind.config.js"]不能解决问题。

I'm pretty sure this is a Typescript issue more than a Tailwind one...我很确定这是一个 Typescript 问题,而不是 Tailwind 问题......

My questions are:我的问题是:

  1. How can I make Typescript aware of the "blue" property on the colors in my tailwind theme, and我怎样才能让 Typescript 知道我顺风主题中 colors 的"blue"属性,以及
  2. How can I stop the tsconfig error from importing the JS config?如何阻止导入 JS 配置时出现 tsconfig 错误?

This looks like it's a problem occurring because of the union types that Tailwind has typed its resolveConfig return value with.这看起来是一个问题,因为 Tailwind 使用联合类型键入了它的resolveConfig返回值。 Essentially, because of the union, TS doesn't know whether the value of fullConfig.theme.colors is an object or a getter function (and likewise, whether fullConfig.theme.colors["blue"] is a string, color-group object or a color function) - presumably this is because this decision is left to the user's tailwind.conf implementation choices, and Tailwind doesn't infer it. Essentially, because of the union, TS doesn't know whether the value of fullConfig.theme.colors is an object or a getter function (and likewise, whether fullConfig.theme.colors["blue"] is a string, color-group object 或颜色函数)——大概是因为这个决定留给用户的 tailwind.conf 实现选择,而 Tailwind 不会推断它。

The easiest way to get around this would probably be to write your own function that takes the union-typed value you're trying to use and returns only the specific type you want, eg.解决这个问题的最简单方法可能是编写自己的 function ,它采用您尝试使用的联合类型值并仅返回您想要的特定类型,例如。

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'];

In terms of why importing your Tailwind config is giving you errors, check your allowJs and checkJS keys in compilerOptions in your TSConfig.至于为什么导入 Tailwind 配置会出现错误,请检查 TSConfig 中compilerOptions中的allowJscheckJS键。 Otherwise, if you're using Create React App, it won't be possible this way at all since you can't import files from outside the src folder.否则,如果您使用 Create React App,则根本不可能这样,因为您无法从src文件夹之外导入文件。

I think maybe you can using the tailwind default config type to resolve like this:我想也许你可以使用tailwind默认配置类型来解决这样的问题:

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
}

Answering the original question #1.回答原始问题#1。
Somehow, typescript can't give you correct typings when doing like so:不知何故, typescript 在这样做时无法为您提供正确的输入:

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

So I figured, that I actually only need the theme (and the content is just required in Config type) and ended up like this:所以我想,我实际上只需要themeConfig类型中只需要content ),结果是这样的:

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;

The only problem here is I can't have /** @type {import('tailwindcss').Config} */ in the config file itself, because IDE starts to resolve types from there instead of the config objects.这里唯一的问题是我不能在配置文件本身中有/** @type {import('tailwindcss').Config} */ ,因为 IDE 开始从那里解析类型而不是配置对象。 But it's mainly an IDE problem and probably resolvable too.但这主要是一个 IDE 问题,也可能可以解决。


As for question #2, I believe adding "allowJs": true in the compilerOptions of tsconfig.json will do the trick.至于问题 #2,我相信在tsconfig.jsoncompilerOptions中添加"allowJs": true就可以了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM