搭建开发环境
1、安装node.js。
2、使用npm全局安装typescript。
1
| npm install -g typescript
|
3、第一个typescript程序:
1
| console.log("hello world!")
|
进行编译:
编译成功后会生成hello_world.js文件。
基本类型
基本类型
类型 | 例子 | 描述 |
---|
number | 1,33,2.5 | 任意数字 |
string | “hello” | 任意字符串 |
boolean | true、false | 布尔类型 |
字面量 | 其本身 | 限制变量的值就是该自变量的值 |
any | * | 任意类型 |
unknown | * | 类型安全的any |
void | 空值(undefind) | 没有值(undefined) |
never | 没有值 | 不能是任何值 |
object | {name:”小猪”} | 任意的js对象 |
array | [1,2,3] | 任意js数组 |
tuple | [4,5] | 固定长度的数组 |
enum | enum(A,B) | 枚举类型 |
声明变量
1 2 3 4 5 6 7 8 9 10 11 12
| let a: number;
let b: string; let c: boolean = true; let d = false;
function sum(a: number, b: number): number { return a + b; }
|
变量类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| let e: 10;
let f: "male" | "female"; f = "male";
let g: boolean | string;
let h: any; h = 10; h = "hello";
let i: unknown; i = 10; i = "hello";
b = i as string; b = <string>i;
function Jun(): never { throw new Error("报错了!"); }
let j: object; j = {};
let k: { name: string, age: number } let l: { name: string, age?: number } let m: { name: string, [propName: string]: any }
let n: (a: number, b: number) => number
let o: string[]; let p: number[]; let q: Array<number>;
let r: [string, string];
enum Gender { Male = 0, Female = 1 } let s: { name: string, gender: Gender }; s = { name: "小猪猪", gender: Gender.Female }
type MyType = string | boolean | object; let u: MyType;
|
编译选项
热加载单个文件
热加载所有文件
tsconfig.json属性
1 2 3 4 5 6 7 8 9
| { "include": [ "./src/**/*" ]
}
|
1 2 3 4 5 6
| { ... "exclude": [ "./src/noc/**/*" ] }
|
1 2 3 4 5
| { "files": [ "src/app/app.ts" ] }
|
属性 | 含义 | 可选值 |
---|
target | 指定ts被编译的ES的版本 | “ES3”, “ES5”, “ES6”, “ES2015”, “ES2016”, “ES2017”, “ES2018”, “ES2019”, “ES2020”, “ES2021”, “ES2022”, “ESNext” |
module | 指定要使用的模块化的规范 | “CommonJS”, “AMD”, “System”, “UMD”, “ES6”, “ES2015”, “ES2020”, “ESNext”, “None”, “es2022”, “node12”, “nodenext” |
lib | 用来指定项目中要使用的库 | ……(一般不需要动) |
outDir | 用来指定编译后文件所在的目录 | “./dist” |
outFile | 将编译后的文件合并到一个文件中 | “./dist/app.js” |
allowJs | 是否对js文件进行编译 | true、false |
checkJs | 是否检查js代码规范 | true、false |
removeComments | 是否移除注释 | true、false |
noEmit | 不生成编译后的文件 | true、false |
noEmitOnError | 有错误时不生成文件 | true、false |
alwaysStrict | 是否开启严格模式 | true、false |
noImplicitAny | 是否不允许默认属性类型为any | true、false |
noImplicitThis | 是否不允许不明确类型的this | true、false |
strictNullChecks | 是否严格检查空值 | true、false |
strict | 所有严格检查的总开关 | true、false |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| { ... "compilerOptions": { "target": "es6", "module": "es2015", "lib": ["dom"], "outDir": "./dist", "outFile": "./dist/all.js", "allowJs": false, "checkJs": false, "removeComments": false, "noEmit": false, "noEmitOnError": false, "alwaysStrict": false, "noImplicitAny": false, "noImplicitThis": false, "strictNullChecks": false, "strict": false, } }
|
使用webpack打包TS代码
1、项目初始化
生成package.json
2、安装依赖
1
| npm i -D webpack webpack-cli typescript ts-loader
|
-D 开发依赖
Refusing to install package with name “webpack” under a package?
修改package.json中的name属性不为webpack即可。
3、配置webpack.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| const path = require("path");
module.exports = { mode: "development", entry: "./src/index.ts",
output: { path: path.resolve(__dirname, "dist"), filename: "bundle.js", },
module: { rules: [ { test: /\.ts$/, use:'ts-loader', exclude:/node-moudules/, }, ], }, };
|
4、创建tsconfig.json
1 2 3 4 5 6 7
| { "compilerOptions": { "module": "es6", "target": "es6", "strict": true } }
|
5、修改package.json,添加指令
1 2 3 4
| "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack" },
|
6、自动生成html文件并引入js
1
| npm i -D html-webpack-plugin
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| ...
const HTMLWebpackPlugin=require('html-webpack-plugin')
module.exports = { ... plugins:[ new HTMLWebpackPlugin( { template:"./src/index.html" } ), ] };
|
7、配置webpack服务器
1
| npm i -D webpack-dev-server
|
1 2 3 4 5
| "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack", "start": "webpack serve --open" },
|
执行npm start 热更新。
8、编译前删除已编译文件插件
1
| npm i -D clean-webpack-plugin
|
1 2 3 4
| const { CleanWebpackPlugin } = require("clean-webpack-plugin"); plugins: [ new CleanWebpackPlugin(), ],
|
9、设置可以引用的模块
1 2 3 4 5 6 7 8
| module.exports = { ... resolve: { extensions: [".ts", ".js"], }, };
|
10、使用Babel解决多浏览器版本兼容问题
1
| npm i -D @babel/core @babel/preset-env babel-loader core-js
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| output: { ... environment:{ arrowFunction:false } }, module: { rules: [ { test: /\.ts$/, use: [ { loader: "babel-loader", options: { presets: [ [ "@babel/preset-env", { targets: { chrome: "88", }, "corejs": "3", useBuiltIns: "usage", }, ], ], }, }, "ts-loader", ], exclude: /node-moudules/, }, ], },
|
面向对象
类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| class Person { name: string; age: number; static beautiful: boolean = true; readonly rich: boolean = false;
constructor(name: string, age: number) { this.name = name; this.age = age; }
sayHello(): void { console.log("I love you."); } static sayPromise(): void { console.log("I will marry you."); } }
const ps = new Person('小猪', 18); console.log(ps.name); console.log(Person.beautiful);
ps.sayHello(); Person.sayPromise();
|
继承
继承之后子类拥有父类所有的方法和属性,子类可以拥有自己的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| class Animal { name: string; age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } sayHi() { console.log("I am an animal."); } }
class Dog extends Animal { constructor(name: string, age: number) { super(name, age); } sayHi() { console.log("I am a Dog."); }
}
class Cat extends Animal { constructor(name: string, age: number) { super(name, age); } sayHi() { console.log("I am a cat!"); } }
const XiaoMing = new Dog('xiaozhu', 19); const XiaoZhu = new Cat('xiaozhu', 19);
|
抽象类
1 2 3 4 5 6 7 8 9 10 11
| abstract class Animal { name: string; age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } abstract sayHi():void; }
|
接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
interface myInterface { name: string; age: number; }
interface myInterface { gender: boolean; sayHello(): void; }
const obj: myInterface = { name: "xiaozhu", age: 18, gender: false, sayHello(): void { console.log("good morning."); } }
class MyClass implements myInterface { name: string; age: number; gender: boolean; constructor(name: string, age: number, gender: boolean) { this.age = age; this.name = name; this.gender = gender; } sayHello(): void { console.log("hello");
} }
|
属性的封装
类的属性不能直接赋值,而应当由方法进行修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| class Person { private _name: string; private _age: number; constructor(name: string, age: number) { this._name = name; this._age = age; } getName(): string { return this._name; } setName(name: string): boolean { this._name = name; return true; }
get name() { return this._name; } set name(name: string) { this._name = name; } }
const pers = new Person01("小猪", 18);
console.log(pers.name);
pers.name = "可爱猪猪";
|
补充:
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Animal { name: string; age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } }
class Animal{ constructor(public name:string,public age:number){ } }
|
泛型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| function fn<T>(a: T): T { return a; }
fn(10); fn<string>('hello');
function fn2<T, K>(a: T, b: K): T { return a; }
fn2<number, string>(123, 'hello');
interface Inter { length: Number }
function fn3<T extends Inter>(){
}
|
基于typescript的贪食蛇游戏:github