携手创作,共同成长!这是我参与「掘金日新计划 · 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变化爆出了类型检查错误
- 由于我们获取的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');
复制代码
- 这样写之后,会出现报错
- undefined类型从哪里来的?通过鼠标悬浮在inject上,我们可以看到inject函数返回的内容是
TodosStore | undefined
- 想要去除掉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地址点击这里查看