TypeScript 如何进行断言,可以让后续不必写重复的断言?

如下面的例子

const getStrLength = (target: string | number): number => {
  if (typeof target === "string") {
    return target.length; // 这里的`target`被识别为`string`,不用写`(target as string)`
  } else {
    return target.toString().length;
  }
};

那要是不能用typeof进行识别的类型,如何写这个if可以在后续内容中省略断言呢?

function getSomething(target: Event): number | string {
  if (??? MouseEvnet ???) { // 这里怎么写可以省略下面的`(target as MouseEvent)`
    console.log(target.clientX);
    console.log(target.clientX);
    console.log(target.clientX);
    .... // 多行代码总不能每次都写`(target as MouseEvent)`吧
    return target.clientX;
  } else if (??? KeyboardEvent ???) {
    return target.key;
  } else {
    ...
  }
}

有大佬回复用收窄 instanceof可以解决,但是在自定义的类型并不能使用这个功能:

getStrLength(target: MyType1 | MyType2): number {
    if (target instanceof MyType1) { // TS2693: 'ObjectType' only refers to a type, but is being used as a value here.
      return target.a;
    } else {
      return target.length;
    }
  }

image.png
这种情况又该怎么办呢?

阅读 2k
3 个回答

这个功能叫narrowing

function foo(e: Event) {
  if(e instanceof MouseEvent) {
    // todo
  } else if (e instanceof KeyboardEvent) {
    // todo
  }
}

或许你可以了解下类型守卫

根据答主提供的内容,这里我自己整理一下解决办法。

大致思路

声明一个方法专门用来判断是否是某种类型,当然要用TypeScript的写法,这样在if()中使用这个方法后,后续内容中就默认为这种类型了

实现代码

type MyType1 = { a: 1 };
type MyType2 = [1, 2, 3];

// 就是这里
function isMyType1(target: MyType1 | MyType2): target is MyType1 {
  return (target as MyType1).a !== undefined;
}

getNumber(target: MyType1 | MyType2): number {
  if (isMyType1(target)) {
    return target.a;
  } else {
    return target.length;
  }
}
  1. 官方文档:https://www.typescriptlang.or...
  2. 英文阅读困难看这里:https://blog.csdn.net/i042416...
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进