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

有两个类,互为调用关系

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.8k
3 个回答

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 的初始化应该从实例中搬出来,作为静态初始化(静态函数,或者模块级)
class One {
  private classTwo: Two;

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

  public dispatch(type: DispatchType, data: DispatchData) {
    switch (type) {
      case 'one':
        if (typeof data === 'string') {
          this.classTwo.functionOne(data);
        }
        break;
      case 'two':
        if (typeof data === 'number') {
          this.classTwo.functionTwo(data);
        }
        break;
      case 'three':
        if (typeof data === 'number') {
          this.classTwo.functionThree(data);
        }
        break;
      default:
        throw new Error('Invalid dispatch type');
    }
  }
}

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);
  }
}

type DispatchType = 'one' | 'two' | 'three';
type DispatchData = string | number;

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

蹲一个大佬,期待更优雅的方式~
05328160.jpg

本文参与了SegmentFault 思否面试闯关挑战赛,欢迎正在阅读的你也加入。

应该不行。TS 是类型系统,它只能在开发期间起作用,提前检查类型错误,提高开发效率。运行时跑的都是 JS,它就没有任何作用了。

推荐问题
logo
Microsoft
子站问答
访问
宣传栏