TypeScript中的类修饰符和抽象类
在 TypeScript 中,有两种常见的操作符用于处理类型和空值:as
和 !
。它们用于类型断言和非空断言,分别用于处理类型和值的问题。本文将介绍它们的用法和区别。
# as
用于类型断言
as
操作符用于告诉编译器你比它更了解某个值的类型,可以将一个值断言为一个特定的类型。这在处理类型不明确或者需要绕过编译器的类型检查时非常有用。
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
在上面的示例中,我们将 someValue
断言为 string
类型,以便获取其 length
属性。这种情况下,编译器会给予相应的类型提示。
但需要注意的是,as
并不会在运行时执行任何操作,它只是告诉编译器如何看待这个值的类型。
# !
用于非空断言
!
操作符用于告诉编译器,一个值不可能为 null
或 undefined
。这在你确定一个值不会为空的情况下使用。
用tsc --strictNullChecks index.ts
运行会有报错提示 error TS2532: Object is possibly 'undefined'
interface Test {
a?: {
c: number;
};
}
const test: Test = {
a: {
c: 123
}
};
console.log(test.a!.c);
在上面的示例中,我们使用 !
操作符告诉编译器 test.a
不会为 null
或 undefined
,因此可以安全地访问 test.a.c
。这可以避免编译器报错,但需要确保你的断言是正确的,否则可能引发运行时错误。
# ?
用于属性描述和属性读取
?
用于属性描述时,表示该属性是可选的,可以省略不写。这在定义类型或接口时非常有用,允许属性的存在是可选的。
type Test = {
a?: {
c: number;
};
};
在属性读取时,?
表示如果属性存在,则返回属性的值,否则返回 undefined
。
console.log(test.a?.c);
这将会编译成类似下面的代码,只有当 a
存在时才会继续访问 c
。
console.log(test.a && test.a.c);
# ??
用于提供默认值
??
操作符用于提供一个默认值,如果属性不存在或为 null
或 undefined
时,会返回默认值。
type Test = {
a: {
c: number;
} | undefined;
};
const test: Test = {
a: {
c: 123
}
};
console.log(test.a?.c ?? 1); // 如果 a 值不存在,则输出 1
与 ||
操作符不同,??
只在属性值为 null
或 undefined
时才会返回默认值,不会受到其他 falsy 值的影响。例如0值
type Test = {
a: {
c: number;
} | undefined;
};
const test: Test = {
a: {
c: 0
}
};
console.log(test.a?.c ?? 1); // 0
console.log(test.a?.c || 1); // 1
总结来说,as
用于类型断言,!
用于非空断言,?
用于属性描述和读取时的空值处理,??
用于提供默认值。根据具体的情况,选择适合的操作符来处理类型和值的问题。