首页
友链
导航
影视
壁纸
统计
留言板
Search
1
el-upload自定义触发按钮及触发上传前判断
763 阅读
2
vue配置二级目录以及nginx多网站部署
676 阅读
3
el-cascader选择任意一级搭配懒加载使用,单选框radio不会触发懒加载
545 阅读
4
js获取昨天今天明天日期
448 阅读
5
window10如何将C盘用户中文名改为英文名
439 阅读
web前端
vue
react
javascript
nuxt
typescript
indexDB数据库
微信小程序
美文欣赏
心情随笔
技术分享
其他
PHP
nodejs
博客api实战项目
typecho
登录
Search
标签搜索
web
vue
node项目实战
js
javascript
typecho
css
vuex
router
nginx
git
element
joe
utils
leaflet
dateFormat
map
date
axios
reg
辰漪
累计撰写
66
篇文章
累计收到
117
条评论
首页
栏目
web前端
vue
react
javascript
nuxt
typescript
indexDB数据库
微信小程序
美文欣赏
心情随笔
技术分享
其他
PHP
nodejs
博客api实战项目
typecho
页面
友链
导航
影视
壁纸
统计
留言板
搜索到
1
篇与
typescript
的结果
2023-05-25
TypeScript笔记
TS简介ts基于javascript语言构建ts是js的超集,对js语法进行了扩展可以在任何支持js的平台运行ts支持es的新特性,并且还新增了一些新的特性,例如一些api,工具,抽象类啊什么的ts支持js的类型,并且新增了一些其他类型(枚举类...)有着丰富的配置选项ts通过配置可以编译成任意版本的js es6 es3等等TS开发环境下载并安装nodejs使用npm全局安装typescript编译器打开cmd或者powershell(管理员打开)输入 npm i -g typescript测试typescript新建一个文件 hello.ts打开cmd输入以下命令进行编译ts文件tsc hello.ts查看是否编译成功,会多一个hello.js文件TS类型声明类型类型描述类型描述number数字string字符串boolean布尔值(true, false)字面量限制变量的值就是该字面量的值any任意类型unknown类型安全的anyvold空值,没有值(undefined)never没有值,不能是任何值objectjs对象arrayjs数组tuple元组,ts新增类型,固定长度数组enum枚举,ts新增类型 先变量类型声明,再进行赋值let a: number; a = 10; a = 20; // a = 'string' // 代码会报错,不能将类型“string”分配给类型“number” console.log(a);类型声明和赋值同时进行(ts会自动判断变量类型)let c = 10; // 相当于 let c: number = 10 c = 20; c = 'string'; // 代码报错 不能将类型“string”分配给类型“number”函数参数,函数返回值类型声明function sum(a: number, b: number): number{ return a + b; } // const count = sum(10, 20, 30); // 代码报错:应有 2 个参数,但获得 3 个 const count = sum(10, 20); console.log('count: ' + count);字面量类型声明 --- 使用 “|” 连接多个类型let e: 10 | 13; e = 10; e = 13; // e = 12; // 不能将类型“12”分配给类型“10”多类型声明 --- 使用 “|” 连接多个类型let d: number | string; d = 1; d = 'string'; // d = false; // 代码报错:不能将类型“boolean”分配给类型“string | number”any和unknown类型let f: any; // 显式any // let f; // 隐式any ts会自动检测类型 f = 1; f = false; f = 'string'; let g: boolean; g = f // any 类型的值 赋值给 其他类型的变量 不会发生报错 let h: unknown; h = 2; h = 'string'; h = true; // g = h; // 代码报错:不能将类型“unknown”分配给类型“boolean” // 我们自己知道 h 就是一个 boolean类型 ts检测器不知道 我们可以自己判断 if (typeof h === 'boolean') { g = h; // 此时不会报错 } // 或者使用 ts 类型断言 直接告诉解析器 变量的类型 g = h as boolean; g = <boolean> h;void和never类型// void 表示空值,该函数没有返回值或者返回值是undefined function fn(): void{ // return 123 代码报错:不能将类型“number”分配给类型“void” return undefined } // never 表示没有值,永远不会有值,没有终点 function fn1(): never{ throw new Error('报错了!') // 抛出错误 程序终止 }object和array类型// object 类型 let a: object; a = {}; a = function () {}; // 使用对象字面量声明类型 --- 可以指定对象中的属性以及类型 // 属性名后面加?表示该属性是可选的 let b: {name: string, age?: number}; // b = {}; //代码报错:类型“{}”缺少类型“{ name: string; age: 18; }”中的以下属性 b = {name: '张三', age: 18}; // b = {name: '张三', age: 18, a: 1, b: 2} 代码报错:只能指定类型中已经存在的属性 // 如果还想要其他属性,可以使用[propName: string]: any; let c: {name: string, age?: number, [propName: string]: any}; c = {name: '李四', a: 1, b: 2}; // 使用箭头函数的形式,设置函数的结构类型 let f: (a: number, b: number) => number; f = function (a, b) { return a + b; } // f = function(a: string, b) { // 两个a的类型不符合 // return 'ss'; // 代码报错:返回值必须符合上述定义返回值类型 // } // array 类型 --- 两种声明写法 // 1. 类型[] 2. Array<类型> let g: string[]; // 字符串数组 g = ['f', 'g']; // g = ['f', 'g', 1] // 代码报错:不能将类型“number”分配给类型“string” let h: Array<number>; // 数字数组元组类型 --- 固定长度的数组// 元组类型 --- 固定长度的数组 // 语法:[string, string, number, ...] let r: [string, number, boolean]; r = ['ss', 12, true]; // 长度符合,且,每个元素的类型也要符合枚举类型 --- 枚举类// enum枚举类型 // 和不同的js对象本质上没什么区别 // 对于开发者来说,相比于拿值类比较判断,枚举类型更加易懂 // 提高易读性和可维护性 // 语法:enum 枚举名称 {} enum Gender { male, // 默认male = 0 female // 默认female = 1 } // let y: {name: string, gender: 0|1}; // console.log(y.gender === 1); let y: {name: string, gender: Gender}; y = {name: '张三', gender: Gender.male} console.log(y.gender === Gender.male);|表示或者 和 &表示且// |表示或者 和 &表示且 let u: 1 | 2; // 对象,既要满足第一个也要满足第二个,即name和age两个属性都要有 let i: {name: string} & {age: number};类型别名 --- 如果一个类型特别长,可以写别名代替type numType = 1 | 2 | 3 | 4 let o: numType; let p: numType; o = 1; p = 2;TS编译选项配置自动编译ts文件(只能自动编译单个ts文件)tsc index.ts -w // 通过-w指令,监听文件的变化,自动编译通过ts配置文件(tsconfig.json)进行编译项目目录下新建tsconfig.json文件此时可直接使用tsc -w命令,自动编译并监听,项目所有ts文件tsconfig.json常用配置项include --- 包含要编译的文件目录以及文件** 表示任意目录,*表示任意文件写法:"include": ["./src/**/*"] src文件夹下的ts文件都要进行编译exclude --- 排除不需要编译的文件目录和文件默认值:["node_modules", "bower_components", "jspm_packages"]** 表示任意目录,*表示任意文件写法:"exclude": ["./exclude/**/*"] exclude文件夹下的ts文件不需要编译extends --- 继承外部json配置文件写法:"extends": "./config/xxx.json"files --- 小项目,或者编译的文件很少,才会使用到这个选项,单独配置要编译的文件写法:"files: ["./src/index.ts", "./src/home.ts"]"compilerOnSave --- 保存ts文件时,是否进行即时编译,布尔值 默认flasebuildOnSave --- 保存ts文件时,是否对文件进行编译,以及其他文件的构建任务,布尔值 默认falsecompilerOptions --- 编译器选项,如何编译ts文件,编译成什么版本都在这个选项中进行配置target --- 指定要编译成那个版本的js默认值:ES3可接受:"ES3", "ES5", "ES6", "ES2015", "ES2016", "ES2017", "ES2018","ES2019", "ES2020", "ES2021", "ES2022", "ES2023", "ESNext"module --- 指定编译成的js文件使用什么模块化规则默认值:target为es3 |es5,默认则是CommonJS规则,否则默认是 ES6/ES2015规则可接受:"CommonJS", "AMD", "System", "UMD", "ES6", "ES2015","ES2020", "ESNext", "None", "ES2022", "Node16", "NodeNext"lib --- 指定运行环境所需要使用的库默认值:浏览器的一些环境,如:DOM,ES5可接受: "ES5", "ES6", "ES2015", "ES2015.Collection", "ES2015.Core", "ES2015.Generator", "ES2015.Iterable", "ES2015.Promise", "ES2015.Proxy", "ES2015.Reflect", "ES2015.Symbol.WellKnown", 等还有许多写法:"lib: ["ES6", "DOM"]"outDir --- 指定ts文件编译后所在的目录outFile --- 将编译后的代码合并到同一个文件(此时模块化规范得是amd|system),不常用allowJs --- 是否对js文件也进行编译默认值:false,不对js文件进行编译checkJs --- 是否对js文件语法进行检查默认值:false,不对js文件语法进行检查removeComments --- 是否移除注释默认值:false, 不移除注释noEmit --- 不要生成编译文件默认值:false,允许生成编译文件noEmitOnError --- 不生成编译文件,如果文件存在错误的话默认值:false,有错误,照样生成编译后的文件strict --- 严格检查的总开关默认值:false,关闭alwaysStrict --- 启用js严格模式默认值:false, 不开启js严格模式noImplicitAny --- 不允许隐式的any类型默认值:false,允许隐式的any类型noImplicitThis --- 不允许不明确的this默认值:false, 允许不明确的thisstrictNullChecks --- 严格检查空值默认值:false,不检查空值strictBindCallApply --- 严格检查call,apply,bind的参数列表strictFunctionTypes --- 严格检查function函数的类型strictPropertyInitialization --- 严格检查属性是否初始化noFallthroughCasesInSwitch --- 检查switch语句包含正确的breaknoImplicitReturns --- 检查函数没有隐式的返回值noUnusedLocals --- 检查未使用的全局变量noUnusedParameters --- 检查未使用的参数allowUnreachableCode --- 允许不可达代码在webpack中使用ts初始化项目创建项目文件夹npm init -y 生成包管理文件package.json文件下载项目依赖包 # webpack项目 npm i webpack webpack-cli webpack-dev-server html-webpack-plugin -D # ts文件编译成js文件 npm i ts-loader typescript -D # 使用bable对js兼容性做处理 npm i babel-loader @babel/core @babel/preset-env core-js -D创建webpack.config.js配置文件 const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { // 入口文件 entry: path.resolve(__dirname, 'src/main.ts'), output: { path: path.resolve(__dirname, 'dist'), // 输出文件目录 filename: 'bundle.js', // 输出文件名称 environment: { arrowFunction: false, // 关闭webpack打包后的自调用箭头函数 }, clean: true, // 每次打包清空上次目录 }, // webpack-dev-server devServer: { host: '127.0.0.1', port: 9223, // 端口号 open: true }, module: { // 处理ts文件 rules: [ { test: /\.ts$/, // use: "ts-loader", use: [ { loader: "babel-loader", options: { presets: [ ["@babel/preset-env", { "targets": {"ie": "11", "chrome": "58"}, corejs: "3", useBuiltIns: "usage" // 按需加载js垫片 使浏览器支持最新api }] ] } }, "ts-loader" ], exclude: path.resolve(__dirname, 'node_modules') } ] }, plugins: [ new HtmlWebpackPlugin({ template: path.resolve(__dirname, 'public/index.html') }) ], optimization: { minimize: true, }, resolve: { extensions: [".js", ".ts"] // 快捷导入 无需写后缀 }, mode: 'production' // development production } 创建tsconfig.json配置文件 { "compilerOptions": { "target": "ES2015", "module": "ES2015", "strict": true } }class 类类的定义class 类名 { // 实例属性 通过实例.属性名调用 属性名: 类型 = 值 属性名: 类型 = 值 // 静态属性 通过类.属性名调用 static 属性名: 类型 = 值 // 只读属性 通过实例.属性名调用 不可修改 readonly 属性名: 类型 = 值 // 只读静态属性 通过类.属性名调用 不可修改 static readonly 属性名: 类型 = 值 // 构造函数 constructor(参数: 类型) { this.属性名 = 参数 }, 方法名() { ... } }类的使用class Dog { // 定义属性 name: string age: number constructor(name: string, age: number) { // 构造函数中进行赋值 this.name = name this.age = age } say() { console.log(this.name + ': 汪汪汪'); } } const dog1 = new Dog('小黑', 2) const dog2 = new Dog('小白', 1.5) console.log(dog1.name , dog1.age); dog1.say() dog2.say()类的继承使用extends关键字实现继承如果要给子类添加新的属性,则必须要在子类构造函数中,使用关键字super类,调用一下父类构造函数,并传递参数,此时才可以在子类添加新的属性class Animal { name: string age: number constructor(name: string, age: number) { this.name = name this.age = age } say() { console.log(this.name + '在叫'); } } /* 使用 extends 实现类继承 如果在子类中写了constructor构造函数,必须要调用super()重写调用一下父类构造函数,否则父类构造函数不会生效 */ class Dog extends Animal { state: number constructor(name: string, age: number, state: number) { super(name, age) // 给子类创建新的属性 this.state = state } // 方法重写 say() { console.log(this.name + ': 汪汪汪!'); } } class Cat extends Animal{ // 方法重写 say() { console.log(this.name + ': 喵喵喵!'); } } const dog = new Dog('小黑', 2, 0) const cat = new Cat('小白', 1.5) dog.say() console.log(dog.state); cat.say() 抽象类使用 abstract class类定义的类,就是抽象类抽象类不能用来创建对象,只能被继承抽象类可以创建抽象方法,抽象方法不能有实现子类必须要对抽象方法进行重写(function(){ /** * 抽象类 使用 abstract class类定义 * 抽象类不能用于创建对象,只能用来继承 * 抽象类可以创建抽象方法,抽象方法不能有实现,子类必须要对抽象方法进行重写 */ abstract class Animal { name: string age: number constructor(name: string, age: number) { this.name = name this.age = age } abstract say(): void } class Dog extends Animal { // 方法重写 say() { console.log(this.name + ': 汪汪汪!'); } } class Cat extends Animal{ // 方法重写 say() { console.log(this.name + ': 喵喵喵!'); } } const dog = new Dog('小黑', 2, 0) const cat = new Cat('小白', 1.5) dog.say() cat.say() })()类的属性封装类的三种属性修饰符public(默认值):属性可以在类,子类,实例对象中进行修改protected:属性,只能在类,子类中进行修改private: 私有属性,只能在类中进行修改私有属性访问,就需要属性封装,类中提供修改和获取属性的方法,降低容错率,避免随意修改属性,使属性更加的安全 (function() { class Person { name: string; // 类,子类,实例对象中都可以进行修改 protected age: number; // 只能在类,子类中进行修改 private sex: number; // 只能在类中进行修改,私有属性 constructor(name: string, age: number, sex: number){ this.name = name; this.age = age; this.sex = sex; } getSex(){ return this.sex; } setSex(sex: number) { if (sex !== 0 && sex !== 1) return // 可以对数据做一些限制,不能随意修改 this.sex = sex; } } const p1 = new Person('张三', 18, 0); // console.log(p1.age); // 代码报错:只能在类“Person”及其子类中访问 // p1.age = 20; // 代码报错:只能在类“Person”及其子类中访问 p1.name = '李四'; // p1.sex = 10; 属性“sex”为私有属性,只能在类“Person”中访问 console.log(p1.getSex()); p1.setSex(1); console.log('修改后的p1:', p1); })()类的简化写法直接在构造其中声明属性,需要添加修饰符// class A { // name: string; // age: number; // constructor(name: string, age: number){ // this.name = name; // this.age = age; // } // } class A { constructor(public name: string, private age: number){ } get _age(){ return this.age } } console.log(new A('张三', 10)); console.log(new A('张三', 10)._age);interface 接口接口用来定义类的结构接口可以当做类型来使用,可以进行类型声明接口里的方法都是抽象方法接口可以重复声明,相同接口会合并属性和方法接口定义类的时候,使用implements关键字实现接口,类必须满足接口定义的结构(function () { type myType = { // 使用type定义类型,不能重复定义相同的type类,会报错 name: string, age: number } // type myType = { // hobby: Array<string> // } interface myInterface { name: string; age: number; say():void // 抽象方法 } interface myInterface { // 多次声明相同接口不会报错 hobby: string[]; } // interface接口:定义类型声明 const obj: myType = {name: '张三', age: 18} let obj2: myInterface obj2 = { name: '张三', age: 18, say() { console.log('hi~'); }, hobby: ['打游戏'] } // interface接口:定义类结构 class Person implements myInterface { name: string; age: number; hobby: Array<string>; constructor(name: string, age: number, hobby: Array<string>) { this.name = name this.age = age this.hobby = hobby }; say (): void { console.log('hi~'); } } const p = new Person('张三', 18, ['健身']) console.log(p); })() generic泛型当遇到类型不明确,无法确定其类型的时候,此时就可以使用泛型泛型名字可以随便起在函数中 function fn<T>(a: T): T{ return a; } // 多个泛型 function fn2<T, K>(a: T, b: K): T{ console.log(b); return a; } // 1. 直接调用 console.log(fn(1)); // 2. 指定泛型类型 console.log(fn<string>('hello')); // 3. 指定多个泛型 console.log(fn2<number, string>(10, 'hello'));在class类中 class D<T>{ name: T; constructor(name: T){ this.name = name } } console.log(new D<string>('张三').name);泛型范围约束使用interface接口约束extends使泛型继承interface接口 // 约束泛型范围 必须要有一个属性 age interface inter{ age: number } function F<T extends inter>(a: T) { return a } F({age: 10})
2023年05月25日
55 阅读
0 评论
1 点赞