EDIT: updated to reflect fixing a typo in question: The question is a little confusing, since your notNullOrUndefined()
doesn't check a.foo
at all, so it's not surprising that those would be different.
请注意,与--strictNullChecks
上,你已经定义了len()
所以这样a
参数是一个A
,因此cannot为空或未定义。所以你不必检查a
本身在里面len()
功能实现;相反,您需要确保您传递给的任何内容len()
是一个有效的A
. So notNullOrUndefined()
是一个坏名字,因为你正在检查foo
参数的值,而不是参数本身。请随意将其更改为类似的内容fooPropertyIsNotNull()
;我暂时离开它。
这里的主要问题是 TypeScript 认识到if (a.foo != null) { ... }
is a 类型保护 https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-type-assertions,并缩小a.foo
to string
在 - 的里面{ ... }
条款。但类型保护不会传播 https://github.com/Microsoft/TypeScript/issues/14891自动退出函数,因此 TypeScript 无法理解这一点notNullOrUndefined()
其本身充当类型保护。
幸运的是,这个问题很常见,TypeScript 提供了用户定义的类型保护 https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards:如果你有一个返回a的函数boolean
这缩小了其参数之一的类型,您可以更改boolean
返回类型为a类型谓词, 使用x is T
句法。这是为了notNullOrUndefined()
:
const notNullOrUndefined = (a: A): a is { foo: string } => {
return a.foo != null;
}
所以函数签名说:如果你传入一个A
,它将返回一个布尔值。如果返回的话true
,那么传入的参数就缩小为{ foo: string }
。现在您将不会收到任何错误,如您所愿:
interface A {
foo: string | undefined;
}
const notNullOrUndefined = (a: A): a is { foo: string } => {
return a.foo != null; // checking a.foo
}
const len = (a: A): number => {
if (notNullOrUndefined(a)){
return a.foo.length; // okay
}
return 0;
}
希望有帮助,祝你好运!