TypeScript 从核心语言方面和类概念的模塑方面对 JavaScript 对象模型进行扩展。
JavaScript 代码可以在无需任何修改的情况下与 TypeScript 一同工作,同时可以使用编译器将 TypeScript 代码转换为 JavaScript。
TypeScript 通过类型注解提供编译时的静态类型检查。
TypeScript 中的数据要求带有明确的类型,JavaScript不要求。
TypeScript 为函数提供了缺省参数值。
TypeScript 引入了 JavaScript 中没有的“类”概念。
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
,在编译时可自行生成。
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博客
使用枚举我们可以定义一些带名字的常量。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
来声明枚举类型。我们在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();
在代码量较大的情况下,为了避免各种变量命名相冲突,可将相似功能的函数、类、接口等放置到命名空间内
作用:
代表内部模块,将项目模块化,减少全局变量,避免污染全局,提供逻辑分组和避免命名冲突
使用:
namespace xx{
内容...
需要暴露的内容
export ...
}
命名空间和模块的区别:
命名空间:内部模块,主要用于组织代码,避免冲突。
模块:ts的外部模块的简称,侧重于代码的复用,一个模块里可能会有很多个命名空间