首页 > 解决方案 > 基于用户提供的配置为我的 React 组件(一个 NPM 包)派生类型?

问题描述

我正在尝试制作一个<Box>可以在所有项目中使用的组件。这就是我想要发生的事情:

import { Box, BoxConfigProvider } from 'my-npm-package';

const myConfig = {
    coreColors: {
        'pink': '#e38e8e'
    }
}

...

const App = () => {
    return (
        <BoxConfigProvider config={myConfig}>
            <Box color="pink--100">
                I'm pink.
            </Box>
        </BoxConfigProvider>
    );
}

color我想要道具的自动完成建议。我的组件采用提供的coreColors并自动生成${colorName}--100通过${colorName}--700(色调和阴影)命名的颜色调色板。

这可行吗?!现在我Box有自己的带有固定颜色的捆绑配置,一切正常,因为我的类型是从keyof typeof BUNDLED_CONFIG.coreColors(例如)派生的,但我希望能够根据我使用它的项目“注入”我自己的颜色。 .

我也只是假设我需要某种 Context / Provider 设置,但我很想避免它。现在我的包有自己config.ts的定义颜色名称、字体大小名称等——我基本上想做同样的事情,但是从包外部获取对象。即使他们从内部提供它package.json——只要我能从中派生出类型!

希望这主要是连贯的。也许我把事情复杂化了??

标签: reactjstypescriptgenerics

解决方案


从 TS 4.1 开始,您可以使用密钥重新映射来完成您的想法:

const colors = {
    pink: '',
    red: '',
};

type BaseColor = keyof typeof colors;
// "pink" | "red"

type Colors = keyof {
    [C in BaseColor as `${C}-100` | `${C}-200`]: string;
};
// "pink-100" | "pink-200" | "red-100" | "red-200"

重要的一点是Colors类型,它期望BaseColor类型是你有色调的所有颜色名称的联合。

至于将它连接到您的BoxConfigProvider组件中,我不确定 TS 是否真的支持它。至少不是直接的。


推荐阅读