了解条件类型的类型推断
Posted
技术标签:
【中文标题】了解条件类型的类型推断【英文标题】:Understanding type inference with conditional types 【发布时间】:2022-01-17 21:49:25 【问题描述】:我很难理解为什么 TypeScript 将这里的 program.options
推断为 ProgramAOptions | ProgramBOptions
。因此它无法编译代码,因为optA
在ProgramBOptions
中不存在。你能解释一下或指向我解释这种行为的文档吗?
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'.*/
【问题讨论】:
【参考方案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
类型,因此您没有空间缩小类型以上是关于了解条件类型的类型推断的主要内容,如果未能解决你的问题,请参考以下文章
Typescript 和 React:使用 React.Component 和条件类型化道具时类型推断失败