一、什么是 TypeScript
先看一下官网上对 TypeScript 的介绍。

关键词:超集
言外之意 JavaScript 的所有用法 TypeScript 都支持。
关键词:Type
TypeScript 强调也是其优点之意是【类型】
为什么需要 Ts 呢?举个小例子:
一个杯子可以装水,也可以当笔筒装杂物。但是,拿装杂物的杯子些许显得不太干净。物有所用,各司其职
。
Js 是弱类型可以定义 number 类型,可以定义 string 类型,这就并未各司其职。
所以,这就诞生了 Ts
二、TypeScript 的安装及运行
安装:npm install -g typescript 或者 yarn add global typescript
确认是否安装成功: tsc -v
在官网中(中文网 -- 练习)可以将 Ts 转换为 Js

浏览器会识别 html / css / js。识别不了 ts,所以此时我们需要将 ts 编译为 js。
打开编辑器(确保在node/npm/typescript都成功的前提下)
第一步:新建文件夹 TS-APP
第二步:TS-APP下面新建一个index.html文件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="./app.js"></script>
</body>
</html>
在<script src="./app.js"></script>若src="./app.ts"会报错

第三步:在TS-APP下面新建一个app.ts文件
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter("world");
let button = document.createElement('button');
button.textContent = "Say Hello";
button.onclick = function() {
alert(greeter.greet());
}
document.body.appendChild(button);
要想在浏览器运行起来,需要将 app.ts 编译转换为 app.js。此时就要进行此命令: tsc app.ts
✅运行完此命令之后,会自动生成一个 app.js 文件。此时浏览器打开,效果如下:

问答区:如果想同时运行多个 ts 文件该如何操作。
此时需要进行此命令tsc --init
命令执行成功之后,会自动生成一个tsConfig.json
文件,此文件则会将帮助所有的 ts 文件编译转换为相应的 js 文件。
✅运行所有 ts 文件,tsc
即可,则会全部转换

在此处,插播推荐两个插件:
Live Server(能够保存的时候,自动更改)
TypeScript Auto Compiler(能够保存之后,不需要执行 **tsc**
命令,自动会生成相应的 js 文件)
三、TypeScript 入门
(一)TypeScript -- 基本数据类型和报错解析
为了让程序有价值,我们需要能够处理最简单的数据单元:数字,字符串,结构体,布尔值等。 TypeScript支持与JavaScript几乎相同的数据类型,此外还提供了实用的枚举类型方便我们使用。
// 基本数据类型
let num = 25;
let float = 25.5;
let hex = 0xf000; // 16进制
let binary = 0b1001; // 2进制
let octal = 0o733; // 8进制
// 重新赋值
num = '25'; // 会报错,可以在终端编写 tsc 进行查看错误❌,如下图7.
// ts原型
let num = 25;
// 等同于
// let num: number = 25;

其他数据类型:string 、boolean 、 any
⚠️注意:在如下例子中:anything 赋予任何值都不会报错,是因为只是给 anything 开辟了一个空间,但是并没有定义其类型。在项目中,尽量避免需用 any,不太利于后期维护。
// boolean
// ts原型
let isLogin = false;
// 等同于
// let isLogin: string = false;
// **----------------------** //
// string
let str: string = 'hello Tc';
// **----------------------** //
// any
let anything; // 等同于 let anything: any
// 没报错的原因,只是开辟了一个空间,但是没有定义其类型
anything = 25;
anything = 'hello'
(二)TypeScript -- 数组 元组 枚举
// 数组 元组 枚举
let names: Array<string> = ['hello', 'word'];
// console.log(names[0]); // hello
// names[0] = 100; // 报错,不能将类型“100”分配给类型“string”。
// names[0] = 'yes';
let number: number[] = [1, 2, 3];
let anyArray: any[] = [1, 'hello', true];
// **----------------------** //
// 元组
let colors: [string, number] = ['hello', 99];
// let colors: [string, number] = [99, 'hello']; // 会报错
// **----------------------** //
// 枚举
enum Color{
Black,
Yellow,
Red,
}
// let myColor: Color = Color.Black; // 输出为 0
// let myColor: Color = Color.Yellow; // 输出为 1
// 若Yellow = 100, 则Red为101
此枚举类型,转换为 js 的时候是函数形式
var Color;
(function (Color) {
Color[Color["Black"] = 0] = "Black";
Color[Color["Yellow"] = 1] = "Yellow";
Color[Color["Red"] = 2] = "Red";
})(Color || (Color = {}));
// let myColor: Color = Color.Black; // 输出为 0
// let myColor: Color = Color.Yellow; // 输出为 1
// 若Yellow = 100, 则Red为101
控制台输出:{0: "Black", 1: "Yellow", 2: "Red", Black: 0, Yellow: 1, Red: 2}
(三)函数相关类型
// 函数的相关类型
function returnValue() {
return 'hello';
}
// console.log(returnValue()); // hello
// 规范写法
function returnNum(): number { // 定义其返回值类型
return 520;
}
// **----------------------** //
// 若函数返回值 -- 空
function sayHello(): void {
console.log('hello @@@@@');
}
sayHello();
// **----------------------** //
// 参数类型
// 不标准写法,已经知道value1和value2的类型。
// 报错内容:参数“value1”隐式具有“any”类型。
// function sumVal(value1, value2) {
// return value1 + value2;
// }
function sumVal1(value1: number, value2: number): number {
return value1 + value2;
// return value1 * value2; // 如果两个参数中有一个不是数值 那么返回的是NAN。但是若为0或者'',返回0。
}
console.log(sumVal1(1, 2)); // 3
// console.log(sumVal1(1, ''));
function sumVal2(value1: number, value2: string): string {
return value1 + value2;
}
console.log(sumVal2(1, 'hello')); // 1hello
// **----------------------** //
// 函数类型
let myFunc: (a: number, b: number) => number;
// 若函数为定义类型,如下则都可以赋值不同类型。
// myFunc = sayHello;
// myFunc();
myFunc = sumVal1; // 将函数 sumVal1 赋予给 myFunc
console.log(myFunc(5, 5)); // 10
⚠️注意:在最开始入 ts 坑时,除开会写 any 之外。印象最深刻的是 void。fuc(): void或者fuc: () => void。类似这样的写法都没少写。但是,碰到 .then。一报错就改成
any
。
void 其实是代表函数返回值为空
时才使用的。所以,不言而喻,.then 为什么会报错了。
(四)对象 object & type
// 对象 object & type
let listObj = {
name: 'Danile',
age: 31
};
// 不正确写法
// 报错内容:需要去包含 name 和 age 两个属性
// listObj = {};
// 报错内容:不能包含别的属性
// listObj = {
// n: 'hello',
// a: 12,
// }
// 最规范写法
// let listObj(name: string, age: number) = {
// name: 'Danile',
// age: 31
// };
// **----------------------** //
// 稍微复杂对象类型
let complex: { data: number[], myFunc: (item: number) => number[] } = {
data: [1, 2, 3],
myFunc: function(item: number): number[] {
this.data.push(item);
return this.data;
}
}
// console.log(complex.myFunc(520));
// **----------------------** //
// type 生成类型
// type MyType = { data: number[], myFunc: (item: number) => number[] };
interface MyType { data: number[], myFunc: (item: number) => number[] };
let complex2: MyType = {
data: [1, 2, 3],
myFunc: function(item: number): number[] {
this.data.push(item);
return this.data;
}
}
console.log(complex2.myFunc(520));
❓type 和 interface 的区别?
(五)union type 检查类型 null undefined never
// union type 检查类型 null undefined never
// union type
let unionType: number | string | boolean = 12;
unionType = '12';
unionType = true;
// 检查类型
let checkType = 10;
if (typeof checkType == 'number') {
console.log('number')
}
// null 和 undefined
// let myNull = 12;
// myNull = null; // 如果"strict": false的时候则不会有问题
let myNull = null;
myNull = undefined;
// never
// never类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never的子类型或可以赋值给never
// 类型(除了never本身之外)。及时any也不可以赋值给never。通常表现为抛出异常或无法执行到终点(例如无限循环)
let x: never;
// x = 123; // 报错:不能将类型“123”分配给类型“never”。
// never的应用场景 抛出异常
function error(message: string): never {
throw new Error(message);
}
// 死循环
function loop(): never {
while (true) {}
}
let y: number;
y = ( () => {
throw new Error('message');
})();
(六)class 类(属性,方法)
✅区分 public protected private 的区别
public: 公共的
private: 当成员被标记成 private时,它就不能在声明它的类的外部访问。
protected: protected修饰符与 private修饰符的行为很相似,但有一点不同, protected成员在派生类中仍然可以访问
// class 类(属性,方法)
class Person {
public name: string;
protected gender: string;
private age: number = 27;
// public username: string;
constructor(name: string, gender: string, public username: string) {
this.name = name;
this.username = username;
this.gender = gender;
}
printAge(age: number) {
this.age = age;
console.log(this.age);
}
setGender(gender: string) {
this.gender = gender;
console.log(this.gender);
}
}
const person = new Person('Danile', '女', 'Ts');
console.log(person.name, person.username);
person.printAge(30);
person.setGender('男');
(七) class set get修饰词 用于隔离私有属性和可公开属性
// 1.class set get修饰词 用于隔离私有属性 和 可公开属性
// 2.class 静态属性和方法
class Person1 {
private _name: string = 'Danile_getName';
// 私用属性赋值
set setName(value: string) {
this._name = value;
}
// 私有属性取值
get getName() {
return this._name;
}
}
let person1 = new Person1();
console.log(person1.getName); // Danile_getName
person1.setName = 'Danile_setName';
console.log(person1.getName); // Danile_setNames
对于 set 和 get 还可以应用在校验等场景。看如下图:

(八)namespace 命名空间
// namespace 命名空间]
namespace myMath {
export const PI = 3.14;
export function sumValue(num1: number, num2: number): number {
return num1 + num2;
}
export function calcCircle(value: number) {
return value * PI
}
}
const PI = 2.88;
console.log(myMath.sumValue(5, 10)); // 10
console.log(myMath.PI); // 3.14
console.log(PI); // 2.88
网友评论