vue3入门33 - todoMvc 项目 - ts类型检查

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第12天,点击查看活动详情

前言

  • 这一节开始,我们给我们的项目添加typeScript类型检查

useTodosStore

  • src\todos\useTodosStore.ts添加类型检查
  • 首先给过滤方法添加类型检查
import type { Filters } from './interface';

export const filters: Filters = {
  all: (todos) => todos,
  active: (todos) => todos.filter((todo) => !todo.completed),
  completed: (todos) => todos.filter((todo) => todo.completed)
};
复制代码
  • 给todos数据添加类型检查
import type { RefTodos } from './interface';
const todos: RefTodos = ref(storage.get(KEY) || []);
复制代码
  • 给显示类型添加类型检查
import type { VisibleType } from './interface';
  
// 显示类型
const visibility: Ref<VisibleType> = ref('all');
复制代码
  • 此时,我们监听浏览器hash变化爆出了类型检查错误

image.png

  • 由于我们获取的hash是个字符串,不一定是我们想要的哪几项,为了保证一致性,我们可以添加类型断言来解决
// 监听浏览器hash变化
const onHashChange = () => {
  const hash = window.location.hash.replace(/#\/?/, '');
  if (filters[hash]) {
    visibility.value = hash as VisibleType;
  } else {
    visibility.value = 'all';
    window.location.hash = '';
  }
};
复制代码

函数返回添加类型

  • 由于后面我们在inject中会调用,想要获得完整的类型检查,我们需要给整个函数也添加类型检查
  • 在interface.ts中添加通用类型检查
import type { ComputedRef, Ref, WritableComputedRef } from 'vue';

export interface TodosStore {
  todos: Ref<Todos>;
  filteredTodos: ComputedRef<Todo[]>;
  remaining: ComputedRef<number>;
  visibility: Ref<VisibleType>;
  allDone: WritableComputedRef<boolean>;
}
复制代码
  • 函数添加类型检查
export const useTodosStore = (): TodosStore => {}
复制代码

useAddTodo

  • inject调用todosStore数据时,需要给inject添加泛型,获得类型检查
const { todos } = inject<TodosStore>('todosStore');
复制代码
  • 这样写之后,会出现报错

image.png

  • undefined类型从哪里来的?通过鼠标悬浮在inject上,我们可以看到inject函数返回的内容是TodosStore | undefined

image.png

  • 想要去除掉undefined,可以通过传入默认参数,添加类型断言来解决
  • 让ts认为我们默认传入的是TodosStore函数,这样就可以通过校验了
const { todos } = inject<TodosStore>('todosStore', {} as TodosStore);
复制代码
  • 然后给整个函数添加类型检查
export interface AddTodo {
  input: Ref<string>;
  addTodo: () => void;
}

export const useAddTodo = (): AddTodo => {}
复制代码

useRemoveTodo

  • 添加类型校验方式是一样的,我们直接上代码
import { inject } from 'vue';
import type { TodosStore, RemoveTodo,Todo } from './interface';

export interface RemoveTodo {
  removeTodo: (todo: Todo) => void;
}

export const useRemoveTodo = (): RemoveTodo => {
  // 拿todo的数据
  const { todos } = inject<TodosStore>('todosStore', {} as TodosStore);
  /**
   * 删除todo
   * @param todo
   */
  const removeTodo = (todo: Todo) => {
    todos?.value.splice(todos.value.indexOf(todo), 1);
  };
  return {
    removeTodo
  };
};


复制代码

useEditTodo

  • 改造方式一样的,我们直接上代码
import { ref, type Ref } from 'vue';
import { useRemoveTodo } from '@/todos/useRemoveTodo';
import type { EditTodo, Todo } from './interface';

export interface EditTodo {
  editingTodo: Ref<Todo | null>;
  editTodo: (todo: Todo) => void;
  doneEdit: (todo: Todo) => void;
  cancelEdit: (todo: Todo) => void;
}

export const useEditTodo = (): EditTodo => {
  const { removeTodo } = useRemoveTodo();

  // 正在编辑的todo
  const editingTodo: Ref<Todo | null> = ref(null);
  // 编辑之前的文本
  const beforeEditText = ref('');
  // 编辑
  const editTodo = (todo: Todo) => {
    editingTodo.value = todo;
    beforeEditText.value = todo.text;
  };
  // 完成编辑
  const doneEdit = (todo: Todo) => {
    if (!editingTodo.value) return;
    todo.text || removeTodo(todo);
    editingTodo.value = null;
  };
  // 取消编辑
  const cancelEdit = (todo: Todo) => {
    editingTodo.value = null;
    todo.text = beforeEditText.value;
  };
  return {
    editingTodo,
    editTodo,
    doneEdit,
    cancelEdit
  };
};
复制代码

总结

  • 这一节我们给项目中几个hook模块添加了类型检查,下一节我们检查下组件中是否完备
  • GitHub地址点击这里查看

猜你喜欢

转载自juejin.im/post/7128925884420997151