【问题标题】:Understanding type inference with conditional types了解条件类型的类型推断
【发布时间】:2022-01-17 21:49:25
【问题描述】:

我很难理解为什么 TypeScript 将这里的 program.options 推断为 ProgramAOptions | ProgramBOptions。因此它无法编译代码,因为optAProgramBOptions 中不存在。你能解释一下或指向我解释这种行为的文档吗?

type ProgramName = 'a' | 'b';

type ProgramAOptions = {
    optA: number;
};

type ProgramBOptions = {
    optB: number;
};

type Program<T extends ProgramName> = {
    name: T;
    options: T extends 'a' ? ProgramAOptions : ProgramBOptions;
};name

function test(p: Program<ProgramName>) : void
{
    if (p.name === 'a')
    {
        p.options.optA = 10; /* this line would not compile with error:

        error TS2339: Property 'optA' does not exist on type 'ProgramAOptions | ProgramBOptions'.
        Property 'optA' does not exist on type 'ProgramBOptions'.*/
    }
}

【问题讨论】:

    标签: typescript type-inference conditional-types


    【解决方案1】:

    通过为每对名称和选项显式声明接口,我将通过以下方式解决您的问题:

    type ProgramName = 'a' | 'b';
    
    interface ProgramAOptions {
        optA: number;
    };
    
    interface ProgramBOptions {
        optB: number;
    };
    
    type ProgramOptions = ProgramAOptions | ProgramBOptions;
    
    interface Program {
        name: ProgramName;
        options: ProgramOptions;
    }
    
    interface ProgramA extends Program {
        name: 'a';
        options: ProgramAOptions;
    }
    
    interface ProgramB extends Program {
        name: 'b';
        options: ProgramBOptions;
    }
    
    type Programs = ProgramA | ProgramB;
    
    function test(p: Programs): void {
        if (p.name === 'a') {
            p.name // is of type "a"
            p.options.optA = 10; // Works
        }
    }
    

    TypeScript playground

    【讨论】:

    • 这确实很好用,+1,不过我很想知道为什么“条件类型”的方式不行。
    • 因为type narrowing 适用于单个变量和联合类型。在您的情况下,您有一个通用类型,您在其中为自己提供了 T 类型,因此您没有空间缩小类型
    猜你喜欢
    • 2018-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 2020-03-18
    • 1970-01-01
    相关资源
    最近更新 更多