Typescript
Typescript入门
安装tsc npm i -g typescript
1.创建一个ts文件
2.使用tsc对ts文件进行编译
进入命令行
进入ts文件所在目录
执行命令 tsc xxx.ts
基础类型
| 数据类型 | 关键字 | 描述 |
|---|---|---|
| 任意类型 | any | 声明为 any 的变量可以赋予任意类型的值。 |
| 数字类型 | number | 双精度 64 位浮点值。它可以用来表示整数和分数。let binaryLiteral: number = 0b1010; // 二进制 let octalLiteral: number = 0o744; // 八进制 let decLiteral: number = 6; // 十进制 let hexLiteral: number = 0xf00d; // 十六进制 |
| 字符串类型 | string | 一个字符系列,使用单引号( ' )或双引号( " )来表示字符串类型。反引号(****)来定义多行文本和内嵌表达式。let name: string = "Runoob"; let years: number = 5; let words: string = 您好,今年是 ${ name } 发布 ${ years + 1} 周年;` |
| 布尔类型 | boolean | 表示逻辑值:true 和 false。let flag: boolean = true; |
| 数组类型 | 无 | 声明变量为数组。// 在元素类型后面加上[] let arr: number[] = [1, 2]; // 或者使用数组泛型 let arr: Array<number> = [1, 2]; |
| 元组 | 无 | 元组类型用来表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同。let x: [string, number]; x = ['Runoob', 1]; // 运行正常 x = [1, 'Runoob']; // 报错 console.log(x[0]); // 输出 Runoob |
| 枚举 | enum | 枚举类型用于定义数值集合。enum Color {Red, Green, Blue}; let c: Color = Color.Blue; console.log(c); // 输出 2 |
| void | void | 用于标识方法返回值的类型,表示该方法没有返回值。function hello(): void { alert("Hello Runoob"); } |
| null | null | 表示对象值缺失。 |
| undefined | undefined | 用于初始化变量为一个未定义的值 |
| never | never | never 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。 |
##### 类型断言
let m = n as string
let m = <string>n
对象
let a: object;
let b = {name: string, [propName: string]: any}
b = {name: 'lihua', gender: 'male', age: 18}
函数类型声明
let d : (a: number, b: number ) => number;
d = function(a, b):number {
return a + b
}
编译选项
自动编译文件
编译文件时,使用-W指令后,TS编译器会自动监视文件的变化,并在文件发生变化时对文件进行重新编译
tsc XXX.ts -W
创建tsconfig.json文件:ts编译器的配置文件
tsc --init // 自动生成tsconfig.json文件
{
//include用来指定哪些文件需要被编译,exclude不被编译的文件
"include": [
"./src/**/*" //任意目录下的任意文件
],
//extends表示被继承的配置文件,相当于引入其他的.json文件
//files指出需要编译的文件
//compilerOptions中包含多个子选项,完成编译相关的配置
compilerOptions: {
"target": "ES3", //用于指定TS被编译为ES的版本es3\es5\es6\es2015\es2016\es2017\es2020\esnext
//module 指定要使用的模块化的规范
"module": "ES2015",
"lib": [], //用来指定项目中需要使用的库
"outDir": "./dist/app.js", //指定编译后文件所在的目录,此处是合并到打包文件的app.js文件
"allowJs": true, //是否对js文件进行编译,默认为false
"checkJs": false, //是否对js文件语法进行编译,默认为false
"removeComments": false, //是否移除注释,默认为false
"noEmit": false, //不生成编译后的文件,默认为false
"noEmitOnError": true, //当有错误时不生成编译后的文件,默认为false
"alwaysStrict": true, //用来设置编译后的文件始终使用严格模式,默认为false
//js文件有模块的导入导出将自动进入严格模式
"noImplicitAny": true, //不允许隐式的any类型,默认为false
"noImplicitThis": true, //不允许不明确类型的this,默认为false
"strictNullChecks": true, //严格检查空值,默认为false
"strict": true, //所有严格检查的总开关,默认为false
}
}
使用webpack打包ts代码
npm init -y //生成package.json配置文件
创建并配置webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
module.exports = {
mode: "development",
entry: './src/index.ts',
output: {
path:path.resolve(__dirname, './dist'),
filename: "bundle.js",
// 通知webpack不使用箭头函数
environment: {
arrowFunction: false // 用于兼容IE
}
},
//配置webpack打包时的模块
module: {
//指定加载时的规则
rules: [
{
//test指定规则生效的文件
test: /.ts$/,
use: [
//配置babel(相关知识点在后面)
{
//指定加载器
loader: 'babel-loader',
options: {
presets: [
[
// 指定环境的插件
"@babel/preset-env",
// 配置信息
{
// 要兼容的目标浏览器
targets: {
"chrome": "88"
},
//指定corejs的版本
"corejs": "3",
//使用corejs的方式 "usage"表示按需加载
"useBuiltIns": "usage"
}
]
]
}
},
'ts-loader'
], // 执行顺序是从后往前
//排除的文件
exclude: /node_modules/
}
]
},
//配置webpack插件
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
//title: "",
template: './src/index.html'
})
],
}
package.json中添加以下代码,通过npm run build运行webpack
"build": "webpack"
\ webpack插件:
npm i -D webpack-dev-server
package.json中添加以下代码,通过npm run start运行webpack
"start": "webpack serve --open chrome.exe"
配置完成后开发实时更新
插件:clean-webpack-plugin 清理dist文件目录
npm i -D clean-webpack-plugin
在webpack.config.js文件中配置plugins对象数组中添加new CleanWebpackPlugin()
webpack.config.js文件中新的配置项,通过resolve设置引用模块
resolve: {
extensions: ['.ts','.js']
}
Babel转换器
作用:新语法转换为旧语法,提高代码兼容性
npm i -D @babel/core @babel/preset-env babel-loader core-js
#### 面向对象
类
class Person {
name: string = "孙悟空";
static age: number = 18;
}
const p = new Person();
在属性前使用static关键字可以定义类属性(静态属性),通过Person.age进行访问
在属性前使用readonly可以将属性设置为只读属性
构造函数和this
class dog(){
// 构造函数会在对象创建时调用
constructor(name: string, age: number){
// 在实例方法中this表示当前的实例
// 在构造方法中当前对象就是当前新建的那个对象
// 可以通过this像新建的对象中添加属性
this.name = name;
this.age = age;
}
}
继承
class Animal(){
// 构造函数会在对象创建时调用
constructor(name: string, age: number){
// 在实例方法中this表示当前的实例
// 在构造方法中当前对象就是当前新建的那个对象
// 可以通过this像新建的对象中添加属性
this.name = name;
this.age = age;
sayHello() {
console.log("叫");
}
}
}
class dog extends Animal{}
重写:在子类中添加父类的同名方法,会覆盖掉继承过来的方法
super关键字
在类的方法中表示当前类的父类
如果在子类中写了构造函数,则必须在其中对父类构造函数进行调用
class Animal(){
// 构造函数会在对象创建时调用
constructor(name: string, age: number){
// 在实例方法中this表示当前的实例
// 在构造方法中当前对象就是当前新建的那个对象
// 可以通过this像新建的对象中添加属性
this.name = name;
this.age = age;
sayHello() {
console.log("叫");
}
}
}
class dog extends Animal{
age: number;
constructor(name: string, age: number) {
// 表示对父类构造函数的调用
super(name);
this.age = age;
}
}
抽象类
以abstract开头的类是抽象类,抽象类与其他类区别不大,只是不能创建对象。
抽象类是专门被继承的类。
抽象类中可以添加抽象方法
abstract class Animal(){
// 构造函数会在对象创建时调用
constructor(name: string, age: number){
// 在实例方法中this表示当前的实例
// 在构造方法中当前对象就是当前新建的那个对象
// 可以通过this像新建的对象中添加属性
this.name = name;
this.age = age;
// 定义抽象方法,抽象方法只能定义在抽象类中,没有方法体
//继承该抽象类的子类必须声明该抽象类的方法体
abstract sayHello(): void;
}
}
}
接口
接口可以在定义类的时候限制类的结构
接口中的所有属性都不能有实际的值
接口只定义对象的结构,而不考虑实际的值,接口中的所有方法都是抽象方法
interface myInter{
name: string;
sayHello(): void;
}
// 实现接口就是使类满足接口的要求
class MyClass implements myInter {
name: string;
constructor (name: string) {
this.name = name
}
sayHello() {
console.log("hello!!!");
}
}
属性的封装
目前属性是在对象中设置的,属性可以被任意修改,会导致一些列问题
作用:对属性进行封装,使属性更加安全,避免随意修改带来的问题
ts可以在属性前添加属性的修饰符
public修饰的属性可以在任意位置修改默认值
private私有属性只能在类内部进行访问修改
可以通过在类内部添加方法使私有属性可以被外部访问修改
class Animal(){
private name: string;
private age: number;
// 构造函数会在对象创建(new)时调用
constructor(name: string, age: number){
// 在实例方法中this表示当前的实例
// 在构造方法中当前对象就是当前新建的那个对象
// 可以通过this像新建的对象中添加属性
this.name = name;
this.age = age;
}
get name() {
return this.name;
}
set name(value: string) {
this.name = value;
}
}
protected修饰符:受保护的属性,只能在当前类和当前类的子类中访问(修改)
class test{
constructor(public name: string, public age: number) {}
}
泛型
在定义函数或者类时,遇到类型不明确就可以使用泛型
function fn<T>(a: T): T{
return a;
}
优点:不像any一样会将ts的类型检查关闭
// 可以直接调用具有泛型的函数
let result = fn(a:10);// 不指定泛型,ts可以自动对类型进行判断
let result2 = fn<string>(a: 'hello');// 指定泛型类型为string
// 泛型可以同时指定多个
function fn2<T, K>(a: T, b: K): T{
console.log(b);
return a;
}
fn2<number, string>(a: 123, b: "hello")
interface Inter{
length: number;
}
// 泛型T必须是Inter实现类(子类)
function fn3<T extends Inter>(a: T): number{
return a.length;
}
fn3(a: '123');// 可行
class MyClass<T>{
name: T;
construcotor(name: T){
this.name = name;
}
}
const mc = new MyClass<string>(name: '孙悟空');
## 练习
项目搭建
package.json、tsconfig.json、webpack.config.js三个配置文件
tsc --init // 自动生成tsconfig.json文件
npm init -y //生成package.json配置文件
webpack.config.js文件需要自行创建并行相关配置
运行指令安装相关loader:
npm i -D less less-loader css-loader style-loader
npm i -D postcss postcss-loader postcss-preset-env
postcss使预处理语言的新语法兼容旧语法
// 在webpack.config.js文件中设置less相关配置
{
test: /.less$/,
use: [ // 这部分加载规则是从后向前加载的
"style-loader",
"css-loader",
// 引入postcss
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env",
{
browsers: "last 2 versions"
}
]
]
}
}
},
"less-loader"
]
}
\