网站搜索

reactjs - 基于不同属性的多重 TypeScript 判别


我正在尝试构建一个支持不同使用场景的复杂 REACT 组件。为了简化它的使用,我想实现 TypeScript 判别类型,以更好地推断 props。

发布完整的例子没有用,但我可以给你展示一个更简单的例子,如下:

interface ICategoryDiscriminationGame {
    category: 'game';
    gameType: 'AAA' | 'AA' | 'A';
}

interface ICategoryDiscriminationProgram {
    category: 'program';
    programType: 'software' | 'freeware';
}

type TCategoryDiscrimination = (ICategoryDiscriminationGame | ICategoryDiscriminationProgram);


interface ISaleDiscriminationPresale {
    saleType: 'pre-sale',
    preSaleCost: number;
}

interface ISaleDiscriminationRetailSale {
    saleType: 'retail',
    retailSaleCost: number;
}

type TSaleDiscrimination = (ISaleDiscriminationPresale | ISaleDiscriminationRetailSale);


type TExampleCompProps = TCategoryDiscrimination & TSaleDiscrimination;

export const ExampleComp = (props: TExampleCompProps) => {
    if (props.category === 'game') { // In here, intellisense infer only use 'props.category' and 'props.saleType' -> NICE
        console.log(props.gameType); // In here, intellisense infer also 'props.gameType' -> NICE
    }

    if (props.saleType === 'pre-sale') { // In here, intellisense infer only use 'props.category' and 'props.saleType' -> NICE
        console.log(props.preSaleCost); // In here, intellisense infer also 'props.preSaleCost' -> NICE
    }

    if (props.category === 'game' && props.saleType === 'retail') { // In here, intellisense infer only use 'props.category' and 'props.saleType' -> NICE
        console.log(props.retailSaleCost); // In here, intellisense infer also 'props.retailSaleCost' and 'props.gameType' -> NICE
        console.log(props.gameType); // In here, intellisense infer also 'props.retailSaleCost' and 'props.gameType' -> NICE
    }

    return <p>In example comp</p>
}

正如你所看到的,在 ExampleComp 内部,智能感知非常出色,工作得也很好。问题是当我尝试使用 ExampleComp 时。
我期望的是,当我输入 <ExampleComp 时,智能感知只允许我使用 category 和 saleType 这两个属性,因为其他属性在未先定义这两个属性时无法存在。但是,实际上,它却建议了所有内容:

所以,这里的问题是:我缺少什么,导致 IntelliSense 无法在 props 中也正常工作?

TS 演示链接

答案#1

这就是 IntelliSense 的本质。一旦你开始提供一些所需属性的组合,建议的属性将会缩小到仅适用于当前可能组合的那些:

在添加一些道具之前:

添加一些道具后: