是否可以让解释器知道我的方法在 TypeScript 中检查 undefined/null
Is it possible to let the interpreter know my method checks for undefined/null in TypeScript
例如,我有一个方法 isEmpty
检查是否有任何内容为空、空或未定义,如果是 returns 则为真。
但是在 TypeScript 中,它不会让解释器知道是这种情况,我在 IDE (WebStorm)
中得到了红色下划线
示例代码
let str: string | undefined = undefined
if (!isEmpty(str)) {
doSomeWorkFunction(str) // this line is shows the error 'string | undefined is not assignable to type string
}
但是如果代码是
let str: string | undefined = undefined
if (str) {
doSomeWorkFunction(str) // no error because the interpreter knows I checked the value
}
我想避免的修复是
let str: string | undefined = undefined
if (!isEmpty(str)){
// @ts-ignore
doSomeWorkFunction(str) // no error since ts is now ignoring this error
}
我怎样才能继续保持 TypeScript 严格的 null 检查,而不必忽略这样的问题。
TypeScript 有一个称为“类型保护”的功能可以帮助解决这种情况:https://www.typescriptlang.org/docs/handbook/advanced-types.html。具体来说,它让您告诉编译器 return 类型不仅是 boolean
,而且是 boolean
,表示输入类型的特定内容。例如,你可以像这样转换一个函数
function isDefinedString(input: string | undefined): boolean
变成这样的函数:
function isDefinedString(input: string | undefined): input is string
return 类型仍然是 boolean
,但现在编译器将假定输入具体是 string
,而不是参数声明允许的任何其他类型(在这种情况 undefined
).
尝试在您现有的 isEmpty
函数声明中使用此签名。虽然不需要让它工作,但因为您要将此附加上下文添加到函数签名中,所以我建议更改 isEmpty
的名称以反映其检查空性和是否定义变量的双重目的。
编辑:
returning 类型信息的一个警告是 returning false 将使编译器假定对象不是该类型。在上面的示例中,如果 isDefinedString
returns false 那么编译器将假定它不是字符串。这会遇到 any
或通用参数的问题,因为 returning false 有效地告诉编译器没有类型(或者用编译器的话来说,“永远”没有类型)满足您的标准.虽然这不会直接导致错误,但编译器没有适用于您的对象的类型这一事实意味着您无法对类型保护触发的 if/else 分支中的对象执行任何有意义的操作 return错误。因此,如果您正在使用诸如 any
或泛型之类的广泛类型,那么如果您打算这样做,您将希望将类型保护所说的内容限制为 input is (null | undefined)
或 input is MySpecificInterface
之类的内容在真假情况下都有意义的东西。这种技巧也可能表明您希望将验证分为两次检查:
if(typeGuard(myObject)) {
if(isValid(myObject)) {
// do something with valid object
} else {
// do something with invalid object
}
}
// do nothing without an object to act upon
例如,我有一个方法 isEmpty
检查是否有任何内容为空、空或未定义,如果是 returns 则为真。
但是在 TypeScript 中,它不会让解释器知道是这种情况,我在 IDE (WebStorm)
中得到了红色下划线示例代码
let str: string | undefined = undefined
if (!isEmpty(str)) {
doSomeWorkFunction(str) // this line is shows the error 'string | undefined is not assignable to type string
}
但是如果代码是
let str: string | undefined = undefined
if (str) {
doSomeWorkFunction(str) // no error because the interpreter knows I checked the value
}
我想避免的修复是
let str: string | undefined = undefined
if (!isEmpty(str)){
// @ts-ignore
doSomeWorkFunction(str) // no error since ts is now ignoring this error
}
我怎样才能继续保持 TypeScript 严格的 null 检查,而不必忽略这样的问题。
TypeScript 有一个称为“类型保护”的功能可以帮助解决这种情况:https://www.typescriptlang.org/docs/handbook/advanced-types.html。具体来说,它让您告诉编译器 return 类型不仅是 boolean
,而且是 boolean
,表示输入类型的特定内容。例如,你可以像这样转换一个函数
function isDefinedString(input: string | undefined): boolean
变成这样的函数:
function isDefinedString(input: string | undefined): input is string
return 类型仍然是 boolean
,但现在编译器将假定输入具体是 string
,而不是参数声明允许的任何其他类型(在这种情况 undefined
).
尝试在您现有的 isEmpty
函数声明中使用此签名。虽然不需要让它工作,但因为您要将此附加上下文添加到函数签名中,所以我建议更改 isEmpty
的名称以反映其检查空性和是否定义变量的双重目的。
编辑:
returning 类型信息的一个警告是 returning false 将使编译器假定对象不是该类型。在上面的示例中,如果 isDefinedString
returns false 那么编译器将假定它不是字符串。这会遇到 any
或通用参数的问题,因为 returning false 有效地告诉编译器没有类型(或者用编译器的话来说,“永远”没有类型)满足您的标准.虽然这不会直接导致错误,但编译器没有适用于您的对象的类型这一事实意味着您无法对类型保护触发的 if/else 分支中的对象执行任何有意义的操作 return错误。因此,如果您正在使用诸如 any
或泛型之类的广泛类型,那么如果您打算这样做,您将希望将类型保护所说的内容限制为 input is (null | undefined)
或 input is MySpecificInterface
之类的内容在真假情况下都有意义的东西。这种技巧也可能表明您希望将验证分为两次检查:
if(typeGuard(myObject)) {
if(isValid(myObject)) {
// do something with valid object
} else {
// do something with invalid object
}
}
// do nothing without an object to act upon