TypeScript 是什么?
TypeScript 是由微软开发的一种自由和开源的编程语言。它是 JavaScript 的一个超集,本质上是在 JavaScript 的基础上添加了可选的静态类型和基于类的面向对象编程。
TypeScript 和 JavaScript 的区别?

TypeScript 的安装
# npm安装
npm install -g typescript
# 验证
tsc -v # Version 4.6.4
# 编译
tsc helloworld.ts # helloworld.ts => helloworld.js
TypeScript 的数据类型
enum Direction {
NORTH = 3, // 默认初始值从0开始, 可手动指定
SOUTH,
EAST,
WEST,
}
enum Direction {
NORTH = "NORTH",
SOUTH = "SOUTH",
EAST = "EAST",
WEST = "WEST",
}
const enum Direction {
NORTH,
SOUTH,
EAST,
WEST,
}
enum Enum {
A,
B,
C = "C",
D = "D",
E = 8,
F,
}
let tupleType: [ string, boolean ];
tupleType = [ "semlinker", true ];
TypeScript 的断言
const someValue: any = "this is a string";
const strLength: number = (<string>someValue).length; // 尖括号写法
const strLength: number = (someValue as string).length; // as写法
function myFunc(maybeString: string | undefined | null) {
// Type 'string | null | undefined' is not assignable to type 'string'.
// Type 'undefined' is not assignable to type 'string'.
const onlyString: string = maybeString; // Error
const ignoreUndefinedAndNull: string = maybeString!; // Ok
}
TypeScript 的接口
interface Person {
name: string;
age?: number; // 可选属性
readonly sex: number; // 只读属性
[ x: string ]: any; // 任意属性
}
let semlinker: Person = {
name: "semlinker",
age: 33,
};
TypeScript 接口与类型别名的区别?
// 接口
interface Point {
x: number;
y: number;
}
interface SetPoint {
(x: number, y: number): void;
}
// 类型别名
type Point = {
x: number;
y: number;
};
type SetPoint = (x: number, y: number) => void;
// primitive
type Name = string;
// object
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };
// union
type PartialPoint = PartialPointX | PartialPointY;
// tuple
type Data = [ number, string ];
// Interface extends interface
interface PartialPointX { x: number; }
interface Point extends PartialPointX {
y: number;
}
// Type alias extends type alias
type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };
// Interface extends type alias
type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }
// Type alias extends interface
interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };
// 与类型别名不同, 接口可以定义多次, 多个接口会被自动合并为单个接口
interface Point { x: number; }
interface Point { y: number; }
const point: Point = { x: 1, y: 2 };
TypeScript 的泛型
function identity <T, U>(value: T, message: U) : T {
console.log(message);
return value;
}
identity<Number, string>(68, "Semlinker");
// 我们也可以完全省略尖括号, 让编译器自动选择这些类型
identity(68, "Semlinker")
// 泛型接口
interface GenericIdentityFn<T> {
(arg: T): T;
}
// 泛型类
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function (x, y) {
return x + y;
};
// 泛型工具类型
// Partial的作用就是将某个类型里的属性全部变为可选项?
// 首先通过keyof T拿到T的所有属性名, 然后使用in进行遍历, 将值赋给P
// 最后通过T[P]取得相应的属性值, 中间的?号用于将所有属性变成可选
type Partial<T> = {
[ P in keyof T ]?: T[ P ];
};
TypeScript 的配置文件
{
"compilerOptions": {
/* 基本选项 */
"target": "es5", // 指定ECMAScript目标版本: 'ES3' (default), 'ES5', 'ES6'/'ES2015', 'ES2016', 'ES2017' or 'ESNEXT'
"module": "commonjs", // 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015'
"lib": [], // 指定要包含在编译中的库文件
"allowJs": true, // 允许编译javascript文件
"checkJs": true, // 报告javascript文件中的错误
"jsx": "preserve", // 指定jsx代码的生成: 'preserve', 'react-native' or 'react'
"declaration": true, // 生成相应的'.d.ts'文件
"sourceMap": true, // 生成相应的'.map'文件
"outFile": "./", // 将输出文件合并为一个文件
"outDir": "./", // 指定输出目录
"rootDir": "./", // 用来控制输出目录结构 --outDir.
"removeComments": true, // 删除编译后的所有的注释
"noEmit": true, // 不生成输出文件
"importHelpers": true, // 从tslib导入辅助工具函数
"isolatedModules": true, // 将每个文件做为单独的模块(与 'ts.transpileModule'类似).
/* 严格的类型检查选项 */
"strict": true, // 启用所有严格类型检查选项
"noImplicitAny": true, // 在表达式和声明上有隐含的any类型时报错
"strictNullChecks": true, // 启用严格的null检查
"noImplicitThis": true, // 当this表达式值为any类型的时候, 生成一个错误
"alwaysStrict": true, // 以严格模式检查每个模块, 并在每个文件里加入 'use strict'
/* 额外的检查 */
"noUnusedLocals": true, // 有未使用的变量时, 抛出错误
"noUnusedParameters": true, // 有未使用的参数时, 抛出错误
"noImplicitReturns": true, // 并不是所有函数里的代码都有返回值时, 抛出错误
"noFallthroughCasesInSwitch": true, // 报告switch语句的fallthrough错误(即不允许 switch的case语句贯穿)
/* 模块解析选项 */
"moduleResolution": "node", // 选择模块解析策略: 'node'(Node.js) or 'classic'(TypeScript pre-1.6)
"baseUrl": "./", // 用于解析非相对模块名称的基目录
"paths": {}, // 模块名到基于baseUrl的路径映射的列表
"rootDirs": [], // 根文件夹列表, 其组合内容表示项目运行时的结构内容
"typeRoots": [], // 包含类型声明的文件列表
"types": [], // 需要包含的类型声明文件名列表
"allowSyntheticDefaultImports": true, // 允许从没有设置默认导出的模块中默认导入
/* Source Map Options */
"sourceRoot": "./", // 指定调试器应该找到TypeScript文件而不是源文件的位置
"mapRoot": "./", // 指定调试器应该找到映射文件而不是生成文件的位置
"inlineSourceMap": true, // 生成单个soucemaps文件而不是将sourcemaps 生成不同的文件
"inlineSources": true, // 将代码与sourcemaps生成到一个文件中, 要求同时设置了 --inlineSourceMap或 --sourceMap属性
/* 其他选项 */
"experimentalDecorators": true, // 启用装饰器
"emitDecoratorMetadata": true // 为装饰器提供元数据的支持
}
}
TypeScript 的 .d.ts
.d.ts 文件是 TypeScript 用来声明变量、模块、type、interface 等等的。
和纯 js 文件相比,在 .d.ts 文件中声明变量或者模块后,在其他地方可以不用 import 导入就能直接使用,并且还有语法提示。
但并不是说创建了 .d.ts 文件,里面声明的东西就能生效,毕竟归根到底它也是 .ts 文件,需要进行预编译,所以需要在 tsconfig.json 文件里面的 include 数组里面添加这个文件。
include 数组里面可以不用写 .d.ts 文件的绝对路径,可以通过 glob 通配符,匹配这个文件所在的文件夹或者是相对路径。
TypeScript 的 declare
.d.ts 文件中的顶级声明必须以 declare 或者 export 修饰符开头。
通过 declare 声明的类型、变量和模块,在 include 包含的文件范围内,都可以直接引用而不用去 import 或者 import type 相应的变量或类型。
// declare声明一个类型
// 在include包含的文件范围内可以直接使用这个type
declare type Asd {
name: string;
}
// declare声明一个模块
// 在编辑ts文件的时候, 如果你想导入一个.css/.less/.png格式的文件, 如果没有经过declare是会提示语法错误的
declare module '*.css';
declare module '*.less';
declare module '*.png';
// declare声明一个变量
// 假如在项目中引入了一个sdk(以微信的sdk为例), 里面有一些全局的对象(比如wx), 但是如果不经过任何的声明, 在ts文件里面直接用wx.config(), 肯定会报错的
// declare就是告诉ts编译器, 你担保这些变量和模块存在, 同时声明了相应类型, 在编译的时候不需要提示错误
// declare声明一个作用域
// 声明完之后在其他地方的ts就可以直接通过API.ResponseList引用到这个接口类型
declare namespace API {
interface ResponseList {}
}
参考文档