typeof
在 TypeScript 中,typeof 操作符可以用来获取一个变量或对象的类型。
获取变量的类型:
function doSome(x: number | string) {if (typeof x === 'string') {// 在这个块中,TypeScript 知道 `x` 的类型必须是 `string`console.log(x.subtr(1)); // Error: 'subtr' 方法并没有存在于 `string` 上console.log(x.substr(1)); // ok}x.substr(1); // Error: 无法保证 `x` 是 `string` 类型}
获取对象的类型: ```typescript interface People { name: string; age: number; }
const me: People = { name: “zzk”, age: 23 }; type Me = typeof me; // type Me = People
- 此外,typeof 也可以用来获取函数对象的类型,比如:```typescriptfunction toArray(x: number): Array<number> {return [x];}type Func = typeof toArray; // -> (x: number) => number[]
instanceof
这有一个关于 class 和 instanceof 的例子:
class Foo {foo = 123;common = '123';}class Bar {bar = 123;common = '123';}function doStuff(arg: Foo | Bar) {if (arg instanceof Foo) {console.log(arg.foo); // okconsole.log(arg.bar); // Error}if (arg instanceof Bar) {console.log(arg.foo); // Errorconsole.log(arg.bar); // ok}}doStuff(new Foo());doStuff(new Bar());
TypeScript 甚至能够理解 else。当你使用 if 来缩小类型时,TypeScript 知道在其他块中的类型并不是 if 中的类型:
class Foo {foo = 123;}class Bar {bar = 123;}function doStuff(arg: Foo | Bar) {if (arg instanceof Foo) {console.log(arg.foo); // okconsole.log(arg.bar); // Error} else {// 这个块中,一定是 'Bar'console.log(arg.foo); // Errorconsole.log(arg.bar); // ok}}doStuff(new Foo());doStuff(new Bar());
in
in 操作符可以安全的检查一个对象上是否存在一个属性,它通常也被作为类型保护使用:
interface A {x: number;}interface B {y: string;}function doStuff(q: A | B) {if ('x' in q) {// q: A} else {// q: B}}
字面量类型保护
当你在联合类型里使用字面量类型时,你可以检查它们是否有区别:
type Foo = {kind: 'foo'; // 字面量类型foo: number;};type Bar = {kind: 'bar'; // 字面量类型bar: number;};function doStuff(arg: Foo | Bar) {if (arg.kind === 'foo') {console.log(arg.foo); // okconsole.log(arg.bar); // Error} else {// 一定是 Barconsole.log(arg.foo); // Errorconsole.log(arg.bar); // ok}}
使用定义的类型保护
JavaScript 并没有内置非常丰富的、运行时的自我检查机制。当你在使用普通的 JavaScript 对象时(使用结构类型,更有益处),你甚至无法访问 instanceof 和 typeof。在这种情景下,你可以创建用户自定义的类型保护函数,这仅仅是一个返回值为类似于someArgumentName is SomeType 的函数,如下:
// 仅仅是一个 interfaceinterface Foo {foo: number;common: string;}interface Bar {bar: number;common: string;}// 用户自己定义的类型保护!function isFoo(arg: Foo | Bar): arg is Foo {return (arg as Foo).foo !== undefined;}// 用户自己定义的类型保护使用用例:function doStuff(arg: Foo | Bar) {if (isFoo(arg)) {console.log(arg.foo); // okconsole.log(arg.bar); // Error} else {console.log(arg.foo); // Errorconsole.log(arg.bar); // ok}}doStuff({ foo: 123, common: '123' });doStuff({ bar: 123, common: '123' });
