前端学习笔记(11)-typescript总结

0.JavaScript 和 TypeScript 的主要差异

TypeScript 从核心语言方面和类概念的模塑方面对 JavaScript 对象模型进行扩展。

JavaScript 代码可以在无需任何修改的情况下与 TypeScript 一同工作,同时可以使用编译器将 TypeScript 代码转换为 JavaScript。

TypeScript 通过类型注解提供编译时的静态类型检查。

TypeScript 中的数据要求带有明确的类型,JavaScript不要求。

TypeScript 为函数提供了缺省参数值。

TypeScript 引入了 JavaScript 中没有的“类”概念。

TypeScript 中引入了模块的概念,可以把声明、数据、函数和类封装在模块中

1.typeScript声明文件

        TypeScript 作为 JavaScript 的超集,在开发过程中不可避免要引用其他第三方的 JavaScript 的库。虽然通过直接引用可以调用库的类和方法,但是却无法使用TypeScript 诸如类型检查等特性功能。为了解决这个问题,需要将这些库里的函数和方法体去掉后只保留导出类型声明,而产生了一个描述 JavaScript 库和模块信息的声明文件。通过引用这个声明文件,就可以借用 TypeScript 的各种特性来使用库文件了。

比如说引入Vue:

declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}

        因为.vue 文件不是一个常规的文件类型,ts 是不能理解 vue 文件是干嘛的,加这一段是是告诉 ts,vue 文件是这种类型的。

        在声明文件(.d.ts)中,关键字 declare 表示声明作用。声明文件用于编写第三方类库,通过配置 tsconfig.json 文件中的 declaration 为 true,在编译时可自行生成。

2.typeScript对比JavaScript新增类型

       tuple(元组类型)、enum(枚举类型)、any(任意类型

2.1 tuple

元组属于数组的一种,元组中的元素可以不必全部保持类型一致

定义元组类型

const list: [string, number] = ['Sherlock', 1887]   // ok
 
const list1: [string, number] = [1887, 'Sherlock']  // error

        元组中规定的元素类型顺序必须是完全对照的,而且不能多、不能少.。虽然可以越界push(不建议),但不可以越界访问。

可选元素类型

const list: [number, string?, boolean?]
list = [10, 'Sherlock', true]
list = [10, 'Sherlock']
list = [10]

        可选元素必须在必选元素的后面,也就是如果一个元素后缀了 ?号,其后的所有元素都要后缀 ?号。

元组类型的 Rest 使用

        元组可以作为参数传递给函数,函数的 Rest 形参可以定义为元组类型:

declare function rest(...args: [number, string, boolean]): void

等价于

declare function rest(arg1: number, arg2: string, arg3: boolean): void

 rest语法:前端学习笔记(6)-常用的es6特性及例子_江正阳的博客-CSDN博客

2.2 enum(枚举类型

使用枚举我们可以定义一些带名字的常量。TypeScript 支持数字的和基于字符串的枚举。

使用场景

枚举类型补充了 JavaScript 的设计不足,很多语言都拥有枚举类型。

当我们需要一组相同主题下的数据时,枚举类型就很有用了。

enum Direction { Up, Down, Left, Right }
 
enum Months { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec }
 
enum Size { big = '大', medium = '中', small = '小' }
 
enum Agency { province = 1, city = 2, district = 3 }


Months.Jan === 0 // true
Months.Feb === 1 // true
Months.Mar === 2 // true
Months.Apr === 3 // true

声明一个枚举类型,如果没有赋值,它们的值默认为数字类型且从 0 开始累加 

  • 通过关键字 enum 来声明枚举类型。
  • TypeScript 仅支持基于数字和字符串的枚举。

3.TypeScript模块与命名空间

3.1 模块

我们在es6中可以通过 export default 声明主导出:

// @filename: hello.ts
export default function helloWorld() {
  console.log("Hello, world!");
}

并导入 

import hello from "./hello.js";
hello();

除了默认导出之外,您还可以通过省略默认导出来导出多个变量和函数 

// @filename: maths.ts
export var pi = 3.14;
export let squareTwo = 1.41;
export const phi = 1.61;

export class RandomNumberGenerator {}

export function absolute(num: number) {
  if (num < 0) return num * -1;
  return num;
}

在另一个文件里用大括号导入: 

import { pi, phi, absolute } from "./maths.js";

console.log(pi);
const absPhi = absolute(phi);

TypeScript 增强了 import 语法,可以只 import module 里的 type 定义。

// @filename: animal.ts
export type Cat = { breed: string; yearOfBirth: number };
'createCatName' cannot be used as a value because it was imported using 'import type'.
export type Dog = { breeds: string[]; yearOfBirth: number };
export const createCatName = () => "fluffy";
// @filename: valid.ts
import type { Cat, Dog } from "./animal.js";
export type Animals = Cat | Dog;

// @filename: app.ts
import type { createCatName } from "./animal.js";
const name = createCatName();

3.2 命名空间 

在代码量较大的情况下,为了避免各种变量命名相冲突,可将相似功能的函数、类、接口等放置到命名空间内

作用:

        代表内部模块,将项目模块化,减少全局变量,避免污染全局,提供逻辑分组和避免命名冲突 

使用:

namespace xx{ 
    内容... 
    需要暴露的内容 
        export ... 
}

命名空间和模块的区别:
命名空间:内部模块,主要用于组织代码,避免冲突。
模块:ts的外部模块的简称,侧重于代码的复用,一个模块里可能会有很多个命名空间

  • 一般认为模块是内部的,typescript中需要import才能暴露出来。在前端代码中,在手写的其他javascript中一定需要require才能找到。
  • 一般认为命名空间是全局的,会污染环境,ts中也需要通过import才能找到。在前端代码中,在手写的其他javascript代码中,直接引用全局变量也是可以找到的(当然之前要先include),require也是可以找到。
  • 一般认为module声明需要export。所以服务端的module不带export别人就没法用了(因为不像客户端可以通过include先加入)
  • 一般认为namespace声明不应要export(主要给客户端html用,只要include顺序对了,直接全局限定名就可以访问)。如果namespace也带export,你就认为这是namespace和module作用一样就是了,失去了全局访问的可能性。

你可能感兴趣的:(前端,前端,typescript,学习)