【TS】學習總結
01-TypeScript編譯環境
TypeScript全局安裝
npm install typescript -g
tsc --version //查看版本,安裝成功
TypeScript運行環境
-
常規路徑
tsc demo.ts//demo.ts -> demo.js 運行js文件
-
ts-node(類似於node運行js)
npm install ts-node -g //ts-node依賴tslib、@types/node npm install tslib @types/node -g ts-node demo.ts
-
webpack工程環境
- mkdir demo & cd demo npm init npm install typescript tsc --init npm install webpack webpack-cli webpack-dev-server -D npm install ts-loader -D npm install html-webpack-plugin -D - 配置package.json - 配置webpack.config.js ...
02-TypeScript數據類型
數據定義語法
const/let/var name(: Type) = value;
不標明Type則會進行類型推導
基本數據類型
...
Array類型
推薦(TSLint):
const names1: string[] = ["why", "abc", "cba"];
const names2: Array<string> = ["why", "abc", "cba"];
數組類型元素類型相同。
object類型
// 使用類型推斷
const obj = {
name:"afs",
age: 23
};
symbol類型&null類型&undefined類型
...
TypeScript新增數據類型
enum類型
enum Direction {
EAST,
WEST,
NORTH,
SOUTH,
}
const d1 = Direction.EAST; // 0
const d2 = Direction.NORTH; // 2
// 指定值,未賦值的依次遞增
enum Direction {
EAST = 10,
WEST = 20,
NORTH,
SOUTH = 40,
}
/*
console.log(Direction);
{
'10': 'EAST',
'20': 'WEST',
'21': 'NORTH',
'30': 'SOUTH',
EAST: 10,
WEST: 20,
NORTH: 21,
SOUTH: 30
}
*/
console.log(Direction[21]); // NORTH
tuple類型
相較於數組,元素類型不同則為元組。
const num = [111, "sadfdsa"];
num.push(123)
num.push("asdfs")
num // [ 111, 'sadfdsa', 123, 'asdfs' ]
any類型
相對於保留js特性的變量(類型不確定)。
如果需要某個變量的類型不固定,可以顯式定義any。
void類型
如果一個函數沒有返回值,那么它的返回值類型就是void。
- 函數不顯式定義返回類型,則會對返回值進行類型推導,沒有返回值則返回undefined
- 如果定義為void,默認不能有返回值,❗但可以顯式返回undefined
- 如果定義為any,可以返回任何類型
- 如果定義為其他特定類型,則必須有返回值且類型相同,比如undefined則必須顯式返回undefined
function a(): undefined{
console.log(1)
}// 報錯
never類型
never 表示永遠不會發生的類型。
如:一個從來不會有返回值的函數(死循環),一個總是會拋出錯誤的函數。(一切不可能運行到的部分均可以限定為never類型)
function foo(x: string | number ): boolean {
if (typeof x === 'string') {
return true;
} else if (typeof x === 'number') {
return false;
}
// 如果 前面的判斷有遺漏 ,這會報錯:
// - 不是所有條件都有返回值 (嚴格模式下)
// - 或者檢查到無法訪問的代碼
// 但是由於 TypeScript 運行永遠不會被訪問的 `never` 類型
// 你可能會用它來做安全或者詳細的檢查。
const check: never = x;
}
// 如果有開發人員需要zx類型
unknown類型
unknown
類型含義類似於any
。
unknown
類型不能賦值給除了 unknown
或 any
的其他任何類型,使用前必需顯式進行指定類型,或是在類型縮小情況下能夠隱式地進行類型推斷的情況。
函數類型
const func: (n: number, s: string) => void = function func(m: number, n: string): void{
//code block
}
類型別名
type newType = number|string;
字面量類型
let m: 'message' = "message";
//m類型則為確定的'message'類型
m = 'other';//報錯
字面量推斷
function func(m: "a"|"b"|"c"){}
let a = "a";
func(a);//報錯
//reason: a: string,m需要字面量類型,即使a="a"可以避免a更改為其他字符串
// => 改成
func(a as "a"); //或
const a = "a"; //或
const a = "a" as const;
03-TypeScript中函數
有一部分可見02-...[void類型]部分。
function func(m: type, n: type): type{
//code block
}
// 如果參數type不寫會默認是any,返回值type會根據函數體返回值自動類型推斷
匿名函數會根據上下文自動推斷參數類型。
const array = [1, 2, 3];
array.forEach(item => {
//code block
})
//此處item會上下文進行類型推斷: number
對象類型
function func(obj: {m: number, n: string}){}
可選類型
function func(m?: number){}
//m可選
聯合類型
function func(m: number|string){}
//m為其中類型之一
//使用前需要類型縮小或類型斷言
類型斷言as
將不確定的類型轉為更確定的類型。
//強制轉換
const s2n = ("string" as unknown) as number;
...
非空類型斷言!
function func(m?: string){
return m.length;
}
//編譯報錯
//改成 => 逃過編譯階段報錯
function func(m?: string){
return m!.length;
}
可選鏈
//上面代碼可以改成
function func(m?: string){
return m?.length;
}
//如果m不存在則短路直接返回undefined
剩余參數
function func(...args: number[]){}
詳解Typescript里的This - 知乎 (zhihu.com)
函數重載
function sum(m: number, n: number): number;
function sum(m: string, n: string): string;
function sum(m: any, n: any): any{
//code block
}
04-TypeScript類型縮小
將不確定的類型進行類型范圍縮小。
typeof
function func(m: number|string){
if(typeof m === "number") {}
else {} //number
}
平等縮小
//switch
function func(m: "a"|"b"){
switch (m) {
case 'a': break;
case 'b': break;
}
}
//===...
function func(m: "a"|"b"){
if(m === "a") {}
//...
}
instanceof
function func(m: Data:string){
if(m instanceof Data) {}
}
in
type Fish = {swim: () => void}
type dog = {run: () => void}
function func(animal: Fish|dog){
if("swim" in animal) {} //Fish
}
05-TypeScript類
繼承:extends
class Parent{
constructor(){}
}
class Child extends Parent{
constructor(){
super();
}
}
修飾符
public、protected、private、static
readonly
class Parent{
readonly xxx;
//xxx只能在 構造器 或 字段定義時 賦值
constructor(){}
}
存取器
class Parent{
set name(name){}
get name(){}
}
抽象類abstract
...略...
06-TypeScript接口
//對象類型
interface Obj{
name: string,
age?: number,
readonly sex: boolean
}
//索引類型
interface Index{
[index: number]: string
}
//函數類型
interface Func{
(n: number, m: number): number
}
繼承
接口支持多繼承,類只能單一繼承。
多態(面向接口編程)
...略...
Freshness
Freshness | 深入理解 TypeScript (jkchao.github.io)
interface IPerson{
name: string
}
const p: IPerson = {
name: "a",
aname: "a"
} //報錯
//在p的賦值過程中,TypeScript對 對象字面量 進行嚴格檢查
泛型
function foo<T>(arg: T): T {}
// 顯式類型定義
foo<string>("abc")
// 隱式類型推導
foo("abc")
泛型約束
interface ILength{
length: number
}
function getLength<T extends ILength>(args: T){
return args.length;
}
getLength("aaa");
getLength([1, 2]);
getLength({length: 10});
07-TypeScript模塊化開發
模塊化
利用ES Module或CommonJS使文件成為一個獨立的模塊。
// ~/a.ts
const a = 1;
const b = 1;
// ~/b.ts
const a = 1;
const b = 1;
// ↑報錯,沖突
-------------
// ~/a.ts
const a = 1;
const b = 1;
// ~/b.ts
const a = 1;
export const b = 1;
// ↑ok
namespace命名空間
namespace允許在模塊內部進行更小粒度的作用域划分。
類型查找規則
.d.ts文件
進行類型聲明(declare),用來做類型檢測。
內置類型聲明
內置JavaScript運行時的一些標准化API的聲明文件。
TypeScript/lib at main · microsoft/TypeScript (github.com)
外部定義類型聲明
第三方庫的類型聲明,有時安裝第三方庫時沒有內置類型聲明,需要自行下載或配置。
TypeScript: Search for typed packages (typescriptlang.org)
自定義類型聲明
//變量
let name = "name"; //.ts
declare let name: string; //.d.ts
//函數
function foo(){}; //.ts
declare function foo(): void; //.d.ts
//類
class xxx{}; //.ts
declare class xxx{}; //.d.ts
//模塊
export defualt xxx; //.ts
declare module "xxx" {}; //.d.ts
//命名空間
declare namespace ${
function ajax(): void
}//.d.ts
$.ajax()//.ts
tsconfig.json
TypeScript: TSConfig Reference - Docs on every TSConfig option (typescriptlang.org)