这是一个基于更复杂的旧代码的精炼示例。假设您具有这样的功能:
function foo(val: string | number): void {
if (typeof(val) !== 'number') {
throw new Error('val must be a number');
}
// do something with number
}
是否可以编写foo
的签名,以便编译器在调用它后推断val
必须是数字?
const val: string | number = getVal();
foo(val);
// Compiler shouldn't complain here since a string would have cause foo to throw
const x = Math.sqrt(val);
答案 0 :(得分:1)
Function overloads将执行此操作。例如,
function foo(val: string): void;
function foo(val: number): number;
function foo(val: string|number) {
if (typeof(val) !== 'number') {
throw new Error('val must be a number');
}
return Math.sqrt(val);
}
Math.sqrt(foo(123)); // ok
Math.sqrt(foo('asdf')); // not ok
答案 1 :(得分:0)
如果您有一个void
返回函数,其作用是缩小其参数之一的类型,并且如果您运行的是TypeScript 3.7或更高版本,则可以将其设为{{3} },编译器将考虑该断言。断言函数的返回类型以asserts
修饰符开头,后跟我们希望函数断言的条件。此条件可以是函数输入之一的名称,也可以是表示函数输入is
的类型比其声明的类型窄的assertion function。这是我们如何使用foo()
进行的操作:
function foo(val: string | number): asserts val is number {
if (typeof (val) !== 'number') {
throw new Error('val must be a number');
}
// do something with number
}
因此,我们已将void
更改为asserts val is number
。如果函数确实返回,则val
的类型将根据需要从string | number
缩小为number
:
const val: string | number = Math.random() < 0.5 ? "str" : 123;
foo(val);
const x = Math.sqrt(val); // okay
请注意,断言函数仅在void
返回函数上起作用,因此您不能拥有同时充当类型断言和并返回某些值的函数。还有其他警告(例如type predicate)。但是您的问题非常适合断言函数,以至于如果我不了解,我想这是语言设计者之一提出的,目的是展示断言函数的功能! ?
好的,希望能有所帮助;祝你好运!