浅谈TS类型注解

261 阅读4分钟

ref reactive computed define props define emits 的类型注解

在Vue 3中对refreactivecomputeddefinePropsdefineEmits进行类型声明,来提高代码的可读性和类型安全性。

咱先说ref与reactive的区分:

    • reactive:接收对象类型数据并返回一个响应式结果[reactive只能接收对象]
    • ref:接收简单类型或对象类型数据的参数传入并返回一个响应式对象---注:在模板中正常使用,但是在代码中需要.value
    • ref函数内部的实现依赖于reactive函数[ref(18)===ref(value:18)]
  • ref`:用于声明一个响应式的基本数据类型变量。
import { ref } from 'vue';
​
const count = ref<number>(0);

通过ref<number>的语法,我们声明了一个名为count的响应式变量,它的类型为number

  • reactive:用于声明一个响应式对象。
import { reactive } from 'vue';
​
interface Person {
  name: string;
  age: number;
}
​
const person = reactive<Person>({
  name: 'John',
  age: 25,
});

使用reactive<Person>的语法,声明了一个名为person的响应式对象,它的类型为Person接口。

  • computed:用于声明一个计算属性。
import { computed } from 'vue';
​
const doubleCount = computed<number>(() => count.value * 2);

使用computed<number>的语法,声明了一个名为doubleCount的计算属性,它的类型为number。计算属性是一个函数,并返回一个经过计算的值。

  • defineProps:用于声明组件接收的属性。
import { defineProps } from 'vue';
​
interface Props {
  title: string;
  count: number;
}
​
export default {
  props: defineProps<Props>(),
  // ...
}

使用defineProps<Props>()的语法,声明了组件接收的属性类型为Props接口。defineProps函数会根据传入的类型声明定义组件的属性。

  • defineEmits:用于声明组件触发的事件。
import { defineEmits } from 'vue';
​
const emit = defineEmits(['update:name', 'increment']);

使用defineEmits(['update:name', 'increment'])的语法,声明了组件触发的事件类型,其中包括update:nameincrement两个事件。defineEmits函数接受一个字符串数组作为参数,用于定义组件可能触发的事件。

---------------------------------------✔过渡一下先

然鹅,在类型注解中多存在类型注解重复或者猪姐的问题,那么这里就引出了自定义类型来优化我们的代码

---------------------------------------✔再转折一下

自定义类型的两种主要方式interface和type的区别

接口(interface)和类型别名(type)是用于定义自定义类型的两种主要方式。以下是它们之间的区别:

  1. 语法差异:

    • 接口(interface)使用interface关键字进行定义,例如:interface Person { /* 属性和方法定义 */ }
    • 类型别名(type)使用type关键字进行定义,例如:type Person = { /* 属性和方法定义 */ }
  2. 扩展性:

    • 接口(interface)可以通过extends关键字来继承其他接口,以组合多个接口的定义。
    • 类型别名(type)可以使用交叉类型(intersection)&来组合多个类型的定义。
  3. 可读性:

    • 接口(interface)通常用于描述对象的形状(shape),更易于理解和阅读。
    • 类型别名(type)则更通用,可以用于定义除了对象之外的其他类型。
  4. 兼容性:

    • 接口(interface)在类型兼容性检查中,允许进行逆变和协变处理。
    • 类型别名(type)则没有逆变和协变的能力。
  5. 条件类型:

    • 类型别名(type)可以结合条件类型(conditional types)进行更复杂的类型转换和推断。
    • 接口(interface)无法直接使用条件类型。

根据个人的需求和使用场景,可以选择使用接口(interface)或类型别名(type)。一般而言,如果要描述对象的形状和行为,更推荐使用接口;如果需要创建通用的类型别名或联合类型,更适合使用类型别名。

--------------------------------------------------续

字面量和联合类型的使用

字面量:

在TypeScript中,字面量类型可以用来明确指定一个变量、参数或属性的取值只能是特定的字面量值,而不能是其他值。这种方式可以限制变量或参数的取值范围,增加类型的严格性和安全性。

这是一个栗子:

type Fruit = 'apple' | 'banana' | 'orange';
​
let fruit: Fruit;fruit = 'apple';  // 合法
fruit = 'banana'; // 合法
fruit = 'cherry'; // 错误,'cherry' 不是 Fruit 类型的值
联合类型:

在TypeScript中,联合类型(Union Types)允许一个变量或参数具有多个可能的类型。使用联合类型可以增加灵活性,使得变量可以接受多个类型的值。

使用竖线(|)来定义联合类型。

let myVariable: number | string;
myVariable = 10; // 合法
myVariable = "Hello"; // 合法
myVariable = true; // 非法,布尔类型不在联合类型中