为什么在使用联合体类型分隔不同类型的形状时出现错误?

时间:2019-05-22 15:12:42

标签: typescript

给出:

type Data = {
    isRoot: true
} | {
    isRoot: false
    disabled: boolean
    name: string
}

function nameGetter(d: Data): string | false {
    if (d.isRoot) {
        return false        
    } else {
        return d.name // error here: property 'name' doesnt exist on type Data
    }
}

链接:https://www.typescriptlang.org/play/#src=type%20Data%20%3D%20%7B%0D%0A%09isRoot%3A%20true%0D%0A%7D%20%7C%20%7B%0D%0A%09isRoot%3A%20false%0D%0A%09disabled%3A%20boolean%0D%0A%09name%3A%20string%0D%0A%7D%0D%0A%0D%0Afunction%20nameGetter(d%3A%20Data)%3A%20string%20%7C%20false%20%7B%0D%0A%09if%20(d.isRoot)%20%7B%0D%0A%09%09return%20false%09%09%0D%0A%09%7D%20else%20%7B%0D%0A%09%09return%20d.name%0D%0A%09%7D%0D%0A%7D%0D%0A

那是为什么?如果我在isRoot上使用字符串文字

type Data = {
    isRoot: 'true'
} | {
    isRoot: 'false'
    disabled: boolean
    name: string
}

function nameGetter(d: Data): string | false {
    if (d.isRoot === 'true') {
        return false        
    } else {
        return d.name
    }
}

代码可以编译!

1 个答案:

答案 0 :(得分:3)

问题在于,如果没有--strictNullChecksif(d.isRoot)实际上会在两个可能的条件下失败。当elsed.isRoot或为false时,它将落入null块中。观察:

declare const d: Data;
d.isRoot = null; // throws an error only if --strictNullChecks is enabled

您需要启用--strictNullChecks,以确保d.isRoot也不能是null

还要注意,即使没有--strictNullChecks,以下代码也可以正常工作:

function nameGetter(d: Data): string | false {
  if (d.isRoot === true) {
    return false        
  } else {
    return d.name
  }
}