提问,ts可以通过类型判断调用不用函数吗?

作者站长头像
站长
· 阅读数 5

有两个类,互为调用关系

class One {
  private classTwo: Two

  constructor() {
    this.classTwo = new Two()
  }

  public dispatch(type: 'one' | 'two' | 'three', data: string | number) {
    if (type === 'one' && typeof data === 'string') {
      this.classTwo.functionOne(data)
    }
    else if (type === 'two' && typeof data === 'number') {
      this.classTwo.functionTwo(data)
    }
    else if (type === 'three' && typeof data === 'number') {
      this.classTwo.functionThree(data)
    }
  }
}

class Two {

  constructor() {

  }

  public functionOne(data: string) {
    console.log('函数一调用', typeof data)
  }

  public functionTwo(data: number) {
    console.log('函数二调用', typeof data)
  }

  public functionThree(data: number) {
    console.log('函数三调用', typeof data)
  }
}

// 调用
const classOne = new One()
classOne.dispatch('one', "1") // string
classOne.dispatch('two', 1) // number

求问ts有没有什么比较好的优化方式,一大串的ifelse看着太碍眼了,或者可以在调用的时候能够判断类型,比如第一个参数是 'one',第二个参数的类型必须是string

补充:classTwo必须要有三个不同名的函数,所以大概不能用重载了

回复
1个回答
avatar
test
2024-07-08

TypeScript 类型的逻辑关系仅限于编译期,运行期还是需要使用判断。

如果不想用那么多 IF,不妨考虑策略模式。

class One {
  private classTwo: Two
  #fnMap: Record<string, string[]>;

  constructor() {
    this.classTwo = new Two()

    this.#fnMap = {
      "one": ["functionOne", "string"],
      "two": ["functionTwo", "number"],
      "three": ["funcctionThree", "number"]
    };
  }

  public dispatch(type: 'one' | 'two' | 'three', data: string | number) {
    const [fnName, t] = this.#fnMap[type] ?? [];
    if (!fnName || t !== typeof data) { return; }
    (this.classTwo as any)[fnName](data);
  }
}

注意,有两个问题没处理(因为懒)

  1. #fnMap 的值应该是元组,第一个元素应该来自于 class Two
  2. #fnMap 的初始化应该从实例中搬出来,作为静态初始化(静态函数,或者模块级)
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容