相关文章推荐
豪爽的热水瓶  ·  Gradle Dependencies ...·  1 年前    · 
微笑的红烧肉  ·  World Hello - Git ...·  1 年前    · 
本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《 阿里云开发者社区用户服务协议 》和 《 阿里云开发者社区知识产权保护指引 》。如果您发现本社区中有涉嫌抄袭的内容,填写 侵权投诉表单 进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

1.1 声明文件

  • 什么是声明文件?

    声明文件就是给 js 代码补充类型标注. 这样在 ts 编译环境下就不会提示 js 文件"缺少类型".

    声明变量使用关键字 declare 来表示声明其后面的全局变量的类型, 比如:

    // packages/global.d.ts
    declare var __DEV__: boolean
    declare var __TEST__: boolean
    declare var __BROWSER__: boolean
    declare var __RUNTIME_COMPILE__: boolean
    declare var __COMMIT__: string
    declare var __VERSION__: string

    上面代码表示 __DEV__ 等变量是全局, 并且标注了他们的类型. 这样无论在项目中的哪个 ts 文件中使用 __DEV__ , 变量 ts 编译器都会知道他是 boolean 类型.

  • 声明文件在哪里?

    声明文件的文件名是有规范要求的, 必须以 .d.ts 结尾。声明文件放在项目里的任意路径/文件名都可以被 ts 编译器识别, 但实际开发中发现, 为了规避一些奇怪的问题, 推荐放在根目录下.

  • 声明文件对纯js项目有什么帮助?

    即便你只写 js 代码, 也可以安装声明文件, 因为如果你用的是 vscode , 那么他会自动分析 js 代码, 如果存在对应的声明文件, vscode 会把声明文件的内容作为代码提示。

  • 1.2. @types和DefinitelyTyped仓库

    DefinitelyTyped 是一个高质量的 TypeScript 类型定义的仓库。通过 @types 方式来安装常见的第三方JavaScript库的声明适配模块

    1.3. lib.d.ts

    当你安装 TypeScript 时,会顺带安装 lib.d.ts 等声明文件。此文件包含了 JavaScript 运行时以及 DOM 中存在各种常见的环境声明。

  • 它自动包含在 TypeScript 项目的编译上下文中;
  • 它能让你快速开始书写经过类型检查的 JavaScript 代码。
  • 你可以通过指定 —noLib 的编译器命令行标志(或者在 tsconfig.json 中指定选项 noLib: true)从上下文中排除此文件。

    看如下例子

    const foo = 123;
    const bar = foo.toString();

    这段代码的类型检查正常,因为 lib.d.ts 为所有 JavaScript 对象定义了 toString 方法。

    如果你在 noLib 选项下,使用相同的代码,这将会出现类型检查错误:

    const foo = 123;
    const bar = foo.toString(); // Error: 属性 toString 不存在类型 number 上

    1.4. tsconfig.json配置文件

    TS 的项目中, TS 最终都会被编译 JS 文件执行, TS 编译器在编译 TS 文件的时候都会先在项目根目录的 tsconfig.json 文件,根据该文件的配置进行编译,默认情况下,如果该文件没有任何配置, TS 编译器会默认编译项目目录下所有的 .ts .tsx .d.ts 文件。实际项目中,会根据自己的需求进行自定义的配置,下面就来详细了解下 tsconfig.json 的文件配置。

    文件选项配置

  • files : 表示编译需要编译的单个文件列表
  • "files": [
      // 指定编译文件是src目录下的a.ts文件
      "scr/a.ts"
     
  • include: 表示编译需要编译的文件或目录
  • "include": [
      // "scr" // 会编译src目录下的所有文件,包括子目录
      // "scr/*" // 只会编译scr一级目录下的文件
      "scr/*/*" // 只会编译scr二级目录下的文件
     
  • exclude:表示编译器需要排除的文件或文件夹
  • 默认排除node_modules文件夹下文件

    "exclude": [
      // 排除src目录下的lib文件夹下的文件不会编译
      "src/lib"
     
  • extends: 引入其他配置文件,继承配置
  • // 把基础配置抽离成tsconfig.base.json文件,然后引入
    "extends": "./tsconfig.base.json"
  • compileOnSave:设置保存文件的时候自动编译
  • vscode暂不支持该功能,可以使用'Atom'编辑器

    "compileOnSave": true

    执行 tsc --init 生成的ts.config.js会有六个初始设置

    "compilerOptions":{ "target":"es2016", // 指定编译成的是哪个版本的js "module":"commonjs", // 指定要使用的模块化的规范 "esModuleInterop":true, // 兼容JS模块无default的导入 "forceConsistentCasingInFileNames":true, // 兼容JS模块无default的导入 "strict":true, // 所有严格检查的总开关 "skipLibCheck":true // 跳过所有.d.ts文件的类型检查

    Vue3中使用TS

    在Vue组合式API中它会有默认的自动类型注解,另外我们可以使用泛型进行复杂类型注解。

  • 自动类型注解
  • <script setup lang="ts">
    import { ref } from "vue";
    let count = ref(0);
    count.value = "123"; // 不能将类型“string”分配给类型“number”。
    </script>
  • 手动类型注解
  • <script setup lang="ts">
    import { ref } from "vue";
    let count = ref<string|number>(0);
    count.value = "123"; // √
    </script>
  • 复杂类型注解
  • <script setup lang="ts">
    import { ref } from "vue";
    interface List {
    let count = ref<string|number>(0);
    count.value = "123"; // √
    </script>

    Vue3 + TS 组件通信

    // parent.vue
    <my-child :count="count"></my-child>
    // my-child
    // 1. vue自带的定义方式
    defineProps({
        count: [Number] 
    // 2. ts的方式
    interface Props({
        count: number
    defineProps<Props>()
    // parent.vue
    <my-child @say-hello="sayHello"></my-child>
    const sayHello = (message: string) => {
      console.log({ message });
    // my-child
    interface Emits {
      (e: "say-hello", message: string): void;
    let emit = defineEmits<Emits>();
    emit("say-hello", "hello-world");

    VueRouter + TS

  • RouteRecordRaw -> 路由表选项类型
  • const routes: Array<RouteRecordRaw> = [
        path: "/",
        name: "home",
        component: HomeView,
     
  • RouteMeta -> 扩展meta的类型
  • declare module "vue-router" {
      interface RouteMeta {
        // 是可选的
        isAdmin?: boolean;
        // 每个路由都必须声明
        requiresAuth: boolean;
     
  • RouterOptions -> createRouter的配置类型
  • RouteLocationNormalized -> 标准化的路由地址
  • Router -> router的实例类型
  • 调用路由的方式
  • import { userRouter, useRoute } from 'vue-router'
    const router = useRouter() // 类似 this.$router
    const route = useRoute() // 类似 this.$route

    Vuex +TS

  • 导出key
  • 导出key
  • 重写useStore
  • 使用store
  • // store.ts
    import { createStore, Store, useStore as baseUseStore } from "vuex";
    import { InjectionKey } from "vue";
    export interface State {
      count: number;
    // step 3 重写useStore
    export function useStore() {
      return baseUseStore(key);
    // step 1 导入key
    export const key: InjectionKey<Store<State>> = Symbol();
    export default createStore<State>({
      state: {
        count: 1,
      getters: {},
      mutations: {},
      actions: {},
      modules: {},
    
    // main.ts
    import store, { key } from "./store";
    // step 2 导出key
    app.use(store,key)
    // App.vue
    import { useStore } from '@/store'
    // step 4 使用store
    const store = useStore()
    console.log(store.state.count)

    Pinia如何使用TS

  • 首先在main.ts中注册Pina
  • import { createPina } from 'pinia'
    const pinia = createPinia()
    createApp(App).use(pinia).mount('#app')
  • 创建 /stores/counter.ts文件
  • import { defineStore } from 'pinia'
    interface Counter {
        counter: number
    export const useCounterStore = defineStore('counterStore', {
        state: (): Counter => ({
            counter: 0
        actions: {
            add(n : number) {
                this,counter += n
     
  • 在App.vue中使用
  • import { storeToRefs } from 'pinia
    import { useCounterStore } from './stores/counter'
    let counterStore = useCounter()
    let { counter } = storeToRefs(counterStore)
    let handleClick = () => {
        counterStore.add(2)
     
  • Pinia除了选项式写法外,也支持组合式写法,主要利用的就是Vue组合式API来实现的
  • import { defineStore } from 'pinia'
    impoer { ref } from 'vue'
    export const useCounterStore = defineStore('counterStore', () => {
        conter = ref<number>(0)
        return { counter }
    

    Element Plus中如何使用TS

  • 如果使用Volar,在ts.config.json中通过comiplerOptions.types指定全局组件类型"types": ["element-plus/global"],会有更好的提示。
  •