Typescript 类型体操 —— Simple Vue

1,626 阅读1分钟

🤔️要求

实现类似Vue的类型支持的简化版本。

通过提供函数名称SimpleVue(类似于Vue.extenddefineComponent),它应该正确地推断出计算和方法内部的this类型。在此挑战中,我们假设SimpleVue接受带有datacomputedmethods字段的Object作为唯一参数,

  1. data是一个简单的函数,它返回一个公开上下文this的对象,但是您无法访问data中的数据本身或其他计算机值或方法。
  2. computed是将上下文作为this的函数的对象,进行一些计算并返回结果。计算结果应作为简单的返回值而不是函数显示给上下文。
  3. methods是函数的对象,其上下文也与this相同。方法可以访问datacomputed以及其他methods公开的字段。 computedmethods的不同之处在于按原样公开的功能。

SimpleVue的返回值类型可以是任意的。

const instance = SimpleVue({
  data() {
    return {
      firstname: 'Type',
      lastname: 'Challenges',
      amount: 10,
    }
  },

  computed: {
    fullname() {
      return this.firstname + ' ' + this.lastname
    }
  },

  methods: {
    hi() {
      alert(this.fullname.toLowerCase())
    }
  }
})

📖知识点

  1. The ThisType<T> marker interface is simply an empty interface declared in lib.d.ts. Beyond being recognized in the contextual type of an object literal, the interface acts like any empty interface.

🔗知识链接

  1. 知识点: This
  2. 知识点: 范型与函数

😢问题 & 解答

  1. Simple Vue
  2. 解答

🍗场景

type ObjectDescriptor<D, M> = {
  data?: D;
  methods?: M & ThisType<D & M>; // Type of 'this' in methods is D & M
};

function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M {
  let data: object = desc.data || {};
  let methods: object = desc.methods || {};
  return { ...data, ...methods } as D & M;
}

let obj = makeObject({
  data: { x: 0, y: 0 },
  methods: {
    moveBy(dx: number, dy: number) {
      this.x += dx; // Strongly typed this
      this.y += dy; // Strongly typed this
    },
  },
});

obj.x = 10;
obj.y = 20;
obj.moveBy(5, 5);