TypeScript 中的 "asserts value is type" 和 "value is type" 有什么区别?
What is the difference between "asserts value is type" and "value is type" in TypeScript?
TypeScript 具有 is
运算符,可帮助创建用于类型检查的测试函数。最近我看到这个运算符的两种不同实现,其中一种使用 asserts
关键字。
我没有在文档中找到关于这两种使用方式的区别的信息。我试了一下,如果我是对的,asserts
不会让你 return 函数中的任何东西,但除此之外我没有发现任何差异。
这是我测试的代码:
// Asserts and tests the value without returninng anything
function assertIsString(value: unknown): asserts value is string {
if (typeof value !== "string") throw Error("value is not a string");
}
// Tests the value and returns something so it can be used for typecheck
// more explicitly
function testIsString(value: unknown): value is string {
return typeof value === "string";
}
const string = "hello";
const number = 123;
assertIsString(string); // does nothing
assertIsString(number); // throws Error
testIsString(string); // returns true
testIsString(number); // returns false
问题:这两个用例之间还有其他区别吗?
总结:主要区别在于一个抛出而另一个必须在条件中使用。
可能抛出异常的函数 return void
被调用 assertion functions.
这些做出断言(您可能认为它是与编译器创建契约),即如果函数不抛出异常,则 return 值中的谓词将为真。从那时起(在当前范围内),谓词中的类型信息将生效。
return boolean
值的函数被调用 type predicates.
而不是潜在地抛出异常(并导致您的程序停止,除非它被捕获(参见 try...catch
),这些只是 return 一个布尔值。如果布尔值为真,则对于调用谓词的其余范围(例如代码块),谓词将生效。
文档链接针对每个案例(和其他信息)提供了多个示例。这是一个演示:
// predicate
function exists <T>(maybe: T): maybe is NonNullable<T> {
return maybe != null;
}
// assertion
function assertExists <T>(maybe: T): asserts maybe is NonNullable<T> {
if (maybe == null) throw new Error(`${maybe} doesn't exist`);
}
function example1 () {
console.log('example1 begin');
let maybe: string | undefined;
if (exists(maybe)) {
maybe; // string
}
else {
maybe; // undefined
}
console.log('example1 end');
}
function example2 () {
console.log('example2 begin');
let maybe: string | undefined;
assertExists(maybe);
maybe; // string
console.log('example2 end');
}
example1(); // 'example1 begin' then 'example1 end'
example2(); // only 'example2 begin', then exception is thrown: `undefined doesn't exist`
TypeScript 具有 is
运算符,可帮助创建用于类型检查的测试函数。最近我看到这个运算符的两种不同实现,其中一种使用 asserts
关键字。
我没有在文档中找到关于这两种使用方式的区别的信息。我试了一下,如果我是对的,asserts
不会让你 return 函数中的任何东西,但除此之外我没有发现任何差异。
这是我测试的代码:
// Asserts and tests the value without returninng anything
function assertIsString(value: unknown): asserts value is string {
if (typeof value !== "string") throw Error("value is not a string");
}
// Tests the value and returns something so it can be used for typecheck
// more explicitly
function testIsString(value: unknown): value is string {
return typeof value === "string";
}
const string = "hello";
const number = 123;
assertIsString(string); // does nothing
assertIsString(number); // throws Error
testIsString(string); // returns true
testIsString(number); // returns false
问题:这两个用例之间还有其他区别吗?
总结:主要区别在于一个抛出而另一个必须在条件中使用。
可能抛出异常的函数 return void
被调用 assertion functions.
这些做出断言(您可能认为它是与编译器创建契约),即如果函数不抛出异常,则 return 值中的谓词将为真。从那时起(在当前范围内),谓词中的类型信息将生效。
return boolean
值的函数被调用 type predicates.
而不是潜在地抛出异常(并导致您的程序停止,除非它被捕获(参见 try...catch
),这些只是 return 一个布尔值。如果布尔值为真,则对于调用谓词的其余范围(例如代码块),谓词将生效。
文档链接针对每个案例(和其他信息)提供了多个示例。这是一个演示:
// predicate
function exists <T>(maybe: T): maybe is NonNullable<T> {
return maybe != null;
}
// assertion
function assertExists <T>(maybe: T): asserts maybe is NonNullable<T> {
if (maybe == null) throw new Error(`${maybe} doesn't exist`);
}
function example1 () {
console.log('example1 begin');
let maybe: string | undefined;
if (exists(maybe)) {
maybe; // string
}
else {
maybe; // undefined
}
console.log('example1 end');
}
function example2 () {
console.log('example2 begin');
let maybe: string | undefined;
assertExists(maybe);
maybe; // string
console.log('example2 end');
}
example1(); // 'example1 begin' then 'example1 end'
example2(); // only 'example2 begin', then exception is thrown: `undefined doesn't exist`