类型守卫理论
What are type Guards in Typescript
type guards
当我们有特定于特定类型的逻辑时,我们在打字稿中使用。
换句话说:
if (typeof someValue === 'string') { // someValue is guaranteed to be of type string // => therefore we can perform all string operations with it // like call someValue.toLowerCase(), etc. }
我们想强制打字稿允许我们使用一个值,就好像它保证是“x”类型一样。一旦我们运行了类型保护,我们就会向打字稿澄清我们正在使用的值的类型。
类型守卫示例
function sum(a: string | number, b: string | number): string | number { // a and b are either of type string or number // therefore we can only use methods on them, // that are common between strings and numbers // i.e. .toString() and .valueOf() if (typeof a === 'string' && typeof b === 'string') { // both a and b are guaranteed to be of type string // can call all string methods on them return a.toUpperCase() + b.toUpperCase(); } if (typeof a === 'number' && typeof b === 'number') { // both a and b are guaranteed to be of type number // can call all number methods on them return a.toFixed(2) + b.toFixed(2); } if (typeof a === 'string' || typeof b === 'string') { // we don't know if a or b is the string, // so we don't get to call string methods on either one of them return String(a) + String(b); } // we have exhausted all the possibilities // Now a and b are guaranteed to be of type 'number' return a.toFixed(2) + b.toFixed(2); }
我们经常在使用联合类型时使用类型保护,如果我们有一个 or 场景并且我们必须缩小我们正在使用的值的类型以确保我们尝试执行的操作是类型安全的。
检查原语与检查对象
在上面的示例中,我们曾经typeof
缩小类型并使用类型保护,我们只使用typeof
原始值:
- if (typeof someNumber === ‘number’) {保证是一个数字}
- if (typeof someString === ‘string’) {保证是一个字符串}
- if (typeof someBoolean === ‘boolean’) {保证是布尔类型}
对于非原始类型,我们使用instanceof
:
- if (someObject instanceof someClass) {保证是 someClass 类型}
function loop(collection: string[] | string): void { // can only access common methods to both // string[] and string if (Array.isArray(collection)) { // collection is guaranteed to be a string[] collection.push('hello world'); } // The above is the same as if (collection instanceof Array) { // collection is guaranteed to be a string[] collection.push('hello world'); } if (typeof collection === 'string') { // collection is guaranteed to be a string console.log(collection.toUpperCase()); } }
即使 typeof 可以与对象一起使用,它也不能像type guard
in 打字稿一样工作。例如typeof
,javascript 中的数组将返回“object”,但它在 typescript 中不作为类型保护。
每当我们想要缩小联合类型的类型并恢复值的一组特定于类型的属性时,我们都会使用类型保护。