typescript

143 阅读7分钟

搭建环境

使用npm初始化项目

npm init /
npm init -y 默认初始化     生成package.json

创建文件夹 src/index.ts 因为搭建的是ts的开发环境 在package.jsonmain的入口文件是index.ts
           src/utils  放业务相关的可复用的方法
           src/tools  业务无关的纯工具的函数
           src/assets 静态资源 图片、字体文件等
           src/api    接口可复用的方法 封装在api文件夹下
           src/config 一般放配置文件
           typings    为模块书写的一些声明文件
           build      项目打包上线一些配置开发时起本地服务的一些配置 一般就是webpack配置 

全局安装部分依赖

npm install typescript tslint -g  // tslint 对代码和风格检测的工具 和 eslint 差不多

安装完typescript tslint 就可以使用tsc命令

tsc --init        // 生成tsconfig.json  1.8版本添加可以在tsconfig.json里书写注释的支持

使用tsc初始化装置

配置webpack

使用webpack4 尽可能少的需要我们去配置


npm install webpack webpack-cli webpack-dev-server -D

安装完webpack依赖包之后 需要在build文件夹下面添加webpack的配置文件webpack.config.js
在package.json的scripts里添加本地开发的指令 start 
start的指令比较特殊 运行的之后是npm start 其余的指令运行是 npm run xxx

// webpack.config.js 在node环境下运行的 所以使用node模块化
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin }= require('clean-webpack-plugin')
module.exports = {
    entry: "./src/index.ts",  // 入口文件
    output: {
        filename: 'main.js', // 项目编译完的输出文件  ts编译完以后都是ts文件
    },
    resolve: {
        extensions: ['.ts', '.tsx', '.js'],  // 可以自动解析一些文件的拓展 比如引入一个文件没有这个拓展名就是import xxx from './index.js' 加上.js的拓展 可以去掉后缀 会自动在当前文件目录下找到index.js 形式是 数组 加文件的后缀名 
    },
    module: { // 配置对于一些指定后缀文件的处理 比如loader之类的东西
        rules: [{
            test: /\.tsx?$/ // 匹配文件后缀 是一个正则表达式 这个正则表达式匹配的就是一些后缀名称是ts 或者tsx的文件
            user: 'ts-loader', // 匹配ts tsx的一些文件用ts-loader来解析 需要安装ts-loader的开发依赖 cnpm install ts-loader -D 
            exclude: /node_modules/ , // 排除一些文件 用正则表达式
        }]
    },
    devtool: process.env.NOOD_ENV === 'production' ? false : 'inline-source-map', // 调试的时候方便定位到代码 开发的时候调试代码是需要source-map 实际生产打包上线之后是不需要source-map 不需要这个source-map可以增加打包速度 减少一些资源的空间浪费     devServer: {
        // contentBase: './dist', // 本地开发环境运行的时 是基于哪个文件夹作为根目录运行的 这个是webpack4的配置 webpack是static: './dist'
        static: './dist',
        // stats: 'errors-only', // webpack在启动本地服务之后 在控制台打印出哪些信息 关注最多是错误信息 为了简单这里只配置了错误信息 webpack5用了会报错
        compress: false, // 不启动压缩
        host: 'localhost',
        port: 8089,
        
    },
    plugins: [  // cnpm install clean-webpack-plugin html-webpack-plugin -D 安装完要引用
        new CleanWebpackPlugin({
            cleanOnceBeforeBuildPatterns: [./dist]
        }), // 清理一些指定的文件夹或者文件 
        new HtmlWebpackPlugin({ // // 指定一个编译的模板 后面的html文件会基于此模板来进行编译            template: './src/template/index.html' // 编译的时候使用哪个html作为模板
        })
    ]

    
}

// 如何可以获取到process.env.NOOD_ENV 在package.json 里面的start指令启动本地开发服务 刚刚下载的
webpack-dev-server就是用于本来开发的一个服务器 在start里面配置webpack-dev-server 通过--config参数
来指定webpack的配置文件 在webpack-dev-server前面需要借助工具cross-env(cnpm install cross-env -D)
可以传入自己的参数 这里就是传入NOOD_ENV 开发环境传入development
scripts: {
    start: 'cross-env NOOD_ENV=development webpack-dev-server --config ./build/webpack.config.js'
}
// 配置好开发环境之后也有一些配置关于webpack-dev-server的配置项在webpack.config.js里面配置 配置项devServer

// 首先是在全局安装typescript  在自己的项目里也要安装typescript
cnpm install typescript

npm start可以启动项目了

打包代码配置 npm run build

"scripts": { "build": "cross-env NOOD_ENV=production webpack-dev-server --config ./build/webpack.config.js"}

ts数据类型 

类型注解就是ts为一个变量,或者一个对象,一个数组,一个函数,一个类等定义了类型,就是类型注解。就是声明了类型。

1.布尔类型 let生命变量 定义变量名:变量类型 = 给变量赋值 let bool: boolean = true  let bool:boolean  bool = true  不可以把其他类型的值赋值给布尔类型
2.支持二进制、八进制、十进制、十六进制的数字 let num: number = 1234
3.let str: string str = '123'
4.数组类型
    // 写法1
    let arr1: number[]
    arr1 = [5]
    
     // 写法2
     let arr2: Array<number>   arr2 = [5]

     let arr3: {string | number}[]
     arr3 = [1, 'a']
5.元祖类型: 数组赋值的每一项必须和定义是的数据类型、数组长度一致
let tuple: [string, number, boolean]
tumple = ['a', 1, false]
let arr = [string, number, boolean][] = [['q', 1, true]]
如果数组中存在不同类型的元素时,需要加个(), 然后在里面夹上类型定义, 并且用 | 隔开
let arr1: (number | string | number[] | boolean)[] = [1, '4', true, [1, 2, 3]]
数组中同类型的对象如何定义数组:
let arr2: {first: string, second: number}[] = [{
    first: '111',
    second: 1
}, {
    first: '222',
    second: 2
}]
ts 提供了类型别名的形式来代替类型定义
    1) 类型别名: 数组类型定义
    type typeA = {first: string, second: number}
    let arrTypeA: typeA[] = [{first: '111', second: 1}]
    2) 类型别名: 函数参数的定义
    type typeB = { first: number, second: string}
    function funTypeB({first, second}) {
        return first + second;
    }
    funTypeB({ first: 2, second: '222'})
6.枚举类型 用关键词enum定义
enum Roles {
    SUPER_ADMIN,
    ADMIN,
    USER
}
console.log(Roles.SUPER_ADMIN) // 0
console.log(Roles.ADMIN) // 1
console.log(Roles.USER) // 2
// 枚举类型的序列号也可以自己指定
enum Roles {
    SUPER_ADMIN = 1,
    ADMIN = 6,
    USER = 8
}

// 如果只指定第一个为1  那ADMIN 和 USER会自动叠加
// 如果从ADMIN开始指定为6 那么SUPER_ADMIN为0 USER为7
// 也可以通过索引号取值
console.log(Roles[1])
7.any 任何类型
let value: any
value = 'abc'
value = '123'
value = false
const arr4: any[] = [1, 'a']
8.void类型 和 any类型想反 any类型可以表示为任意类型 void表示什么类型都不是 一般我们定义一个函数
这个函数不返回任何值 那么我们要给函数指定一个返回值类型的话就是void类型
const consoleText = (text:string):void => {
    console.log(text)
}
9.nullundefined
let u:undefined
u = undefined
let n:null
n = null
10.never 表示永远不存在的值的类型 函数报错和根本不会有返回值的类似于死循环 函数的返回类型为never类型 
其他类型不可以赋值给never类型 never类型可以赋值给null类型
const errorFun1 = (messsage: string): never => {
    throw new Error(message)
}
const infiniteFunc = (): never => {
    while(true) {

    }
}
// 断言类型
const getLength = (target: string | number): number => {
    if((<string>target).lenth || (target as string).length == 0) {
        return (<string>target).length
    } else {
        return target.toString().length
    }
}
// 如果使用jsx语法 只能用(target as string)指定类型 

ES6--symbol
ts对于symbol的支持是按照ES6标准来的
symbol是es6新增的一种基本数据类型 用来表示一种独一无二的值
创建symbol的值要用Symbol这个构建函数
创建symbol值的时候要在tsconfig.json的ib配置项里引入es2015或者es6

public private protected

public private protected
public 自身调用 子类可以调用 实例调用
private 自身调用
protected 自身调用 子类可以调用

ts函数参数和返回值的定义类型

const funA = () => string = () => { return '1'}  // 这里的string就是来定义函数的返回类型

// 最后一个string 定义函数返回类型 参数后面的number、string则是定义参数数据类型
function funA(first: number, second: string, third: boolean):string {
       return first + second + third;
}

**定义参数类型**

// 参数为数组的类型定义
// 不严谨写法:此时的arr数组里可以是任意类型 any 数
function funA(arr) {

}

// 严谨写法:此时arr数组里的元素只能为字符串
function funA(arr: string[]) {

}

// 参数为对象的类型定义
function funA({first, second}: {first: number, second: number}) {
    return first + second;
}

// 参数为函数的类型定义
function funA(callback: (bl: boolean) => boolean) {
    callback(true)
}

function callback(bl: boolean): boolean {
    return bl
}
funA(callback)

**定义返回值类型**

// 返回对象
function funObj(first: number, second: string): {first: number, second: string} {
    return {first, second}
}
funObj(1, "second")

// 返回数组
function funArr(arr: number[]):number[] {
    let newArr = [...arr]
    return newArr
}
funArr([1, 2, 3])

// 函数返回值是undefined, 仅仅是为了在内部实现某个功能,可以给一个类型注解void,代表没有任何返回值
function funVoid():void {
    // 没有返回值
}

// 因为总是抛出异常,所以error将不会有返回值;never类型表示永远不会有值的一种类型
function funNever(message: string): never {
    throw new Error(message)
}