抽离命名空间
将命名空间的内容抽离出来,通过import引入到其他文件中使用
//在index2.ts文件下 expost namespace B{ export const a = 2 } //在index.ts文件下 import xx from './index2.ts' namespace A{ export namespace C{ export const D = 5 } } console.log(A.C.D,B)//将B抽离成了文件 //将此文件用dsc进行终端编译,然后在tscondig.json将module修改为CommonJs(node.js不认识defined,node.js是基于CommonJS的),进去js文件夹、终端运行node index
简化命名空间
可以给命名空间路径起个名字,然后直接使用这个名字就可以代替命名空间路径了
这个是不能够在ts-node的环境下去使用的
//在index2.ts文件下 expost namespace B{ export const a = 2 } //在index.ts文件下 import xx from './index2.ts' namespace A{ export namespace C{ export const D = 5 } } console.log(A.C.D,B)//将B抽离成了文件 import AAA = A.C.D console.log(AAA)//起到跟A.C.D一样的作用 import AAA = A.C console.log(AAA.D)//起到跟A.C.D一样的作用
命名空间的合并
如果命名空间的命名一样的话(重名),会自动合并
//案例1 namespace A{ export const b = 2 } namespace A{ export const d = 3 } //案例2 namespace A{ export const b = 2 export const d = 3//案例1跟案例2是一模一样的,会自动合并 }
三斜线指令(TS -- 17)
三斜线指令是包含单个XML
标签的单行注释。 注释的内容会做为编译器指令使用。
三斜线指令仅可放在包含它的文件的最顶端。 一个三斜线指令的前面只能出现单行或多行注释,这包括其它的三斜线指令。 如果它们出现在一个语句或声明之后,那么它们会被当做普通的单行注释,并且不具有特殊的涵义。
/// <reference path="..." />
指令是三斜线指令中最常见的一种。 它用于声明文件间的 依赖。
三斜线引用告诉编译器
在编译过程中要引入的额外的文件。也可以认为是另一个import
你也可以把它理解能 import
,它可以告诉编译器在编译过程中要引入的额外的文件
相较于抽离命名空间。范围更广,将整个文件都抽离出来了。
//在a.ts namespace A { export const fn = () => 'a' } //在b.ts namespace A { export const fn2 = () => 'b' } //在index.ts ///<reference path="./index2.ts" /> ///<reference path="./index3.ts" /> //引入之后直接可以使用变量 A console.log(A);
这个时候小满将outFile打开了,这个的作用是:将输出文件合并为一个文件,并编译到指定的路径中
这个时候样式的还在
这个时候,我们再打开removeComments,他的作用是:删除编译后的所有的注释
编译好后,那些样式就不在了
引入声明文件
例如,把 /// <reference types="node" />
引入到声明文件,表明这个文件使用了 @types/node/index.d.ts
里面声明的名字; 并且,这个包需要在编译阶段与声明文件一起被包含进来。
仅当在你需要写一个 d.ts
文件时才使用这个指令。
使用的话,需要将声明文件装起来(npm install @types/node -D)
///<reference types="node" /> //这个node文件他会自己去找
声明文件d.ts(TS -- 18)
声明文件 declare
当使用第三方库
时,我们需要引用它的声明文件,才能获得对应的代码补全、接口提示等功能。
declare var 声明全局变量 declare function 声明全局方法 declare class 声明全局类 declare enum 声明全局枚举类型 declare namespace 声明(含有子属性的)全局对象 interface 和 type 声明全局类型 /// <reference /> 三斜线指令 先:npm init -y
npm init -y 在文件夹下生成默认的 package.json 文件,使用命令生成的 package.json 文件内容与不使用命令生产的不一样
后:npm install express -S 正式线安装
npm install axios
- 从node_modules的axios的package.json可以发现types:"index.d.ts",可以发现声明文件已经被指定了
- 我们在去看index.d.ts文件可以看到最后通过declare将其导出了
- 在引入使用的时候,发现express在引入的时候爆红了
- 同样的在node_nodules可以找到express中的package.json,发现他根本没有types,也就是说没有指定声明文件。所以才会有爆红的这个问题
- 我们可以在根目录下创建一个express.d.ts文件
- 在文件中写入
declare var express:() => any
- 这个时候,我们在使用express的时候,就发现可以使用了
express()
,不会爆红了 - 另一种方法就是按照提示去装包,然后去tsconfig.json去导出一下
"allowSyntheticDefaultImports":true
进行补全
Mixins混入(TS -- 19)
TypeScript 混入 Mixins 其实 vue 也有 mixins 这个东西 你可以把他看作为合并
对象混入
可以使用 ES6
的 Object.assign 合并多个对象
此时 people 会被推断成一个交差类型 Name & Age & sex;
Object.assign()
- Object.assign () 这个方法来实现浅复制
- 主要的用途是用来合并多个 JavaScript 的对象
- Object.assign () 接口可以接收多个参数,第一个参数是目标对象,后面的都是源对象,assign 方法将多个原对象的属性和方法都合并到了目标对象上面,如果在这个过程中出现同名的属性(方法),后合并的属性(方法)会覆盖之前的同名属性(方法)
- Object.assign 拷贝的属性是有限制的,只会拷贝对象本身的属性(不会拷贝继承属性),也不会拷贝不可枚举的属性
- Object.assign 不会跳过那些值为 [null] 或 [undefined] 的源对象
interface Name { name: string } interface Age { age: number } interface Sex { sex: number } let people1: Name = { name: "小满" } let people2: Age = { age: 20 } let people3: Sex = { sex: 1 } //Object.assign(a,b,c) const people = Object.assign(people1,people2,people3)
类的混入
首先声明两个 mixins 类 (严格模式要关闭不然编译不过)
//混入类 class A{ type:boolean changeType(){ this.type = !this.type } } class B{ name:string getName(){ return this.name } } //实现类 首先应该注意到的是,没使用 extends 而是使用 implements。 把类当成了接口。我们可以这么做来达到目的,为将要 mixin 进来的属性方法创建出占位属性。 这告诉编译器这些成员在运行时是可用的。 这样就能使用 mixin 带来的便利,虽说需要提前定义一些占位属性 class C implements A,B{ //这个时候编辑器会给出提示类"C"错误实现"A"。你是想扩展"A"并将其成员作为子继承吗? //类型"C"缺少类型"A"中的以下属性:type,changeType //B类同理 //这个时候就需要我们提前定义占位符 type:boolean = false; name:string = "小余"; changeType:()=> void getName:() => string } mixins(C,[A,B])//第一个为目标对象,后面为要混入的对象 //最后,创建这个帮助函数,帮我们做混入操作。 它会遍历 mixins 上的所有属性,并复制到目标上去,把之前的占位属性替换成真正的实现代码 //帮助函数,把我们在实现类中写的去进行一个实现 function mixins (curClas:any,itemCls:any[]){ itemCls.forEach(item()=>{ console.log(item);//输出[class A][class B],我们要读取的不是这个,而是他原型上的一些属性 Object.getOwnPropertyNames(item,prototype).forEach(name =>{ //Object.getOwnPropertyNames () 可以获取对象自身的属性,除去他继承来的属性,对它所有的属性遍历,它是一个数组,遍历一下它所有的属性名 console.log(name);//打印出来了changeType跟getName curClas.prototype[name] = item.prototype[name] }) }) } let ccc = new C()//实例化一下 console.log(ccc.type);//false ccc.changeType()//这里切换了布尔值 console.log(ccc.type);//true
装饰器Decorator(TS -- 20)
Decorator 装饰器是一项实验性特性,在未来的版本中可能会发生改变
它们不仅增加了代码的可读性,清晰地表达了意图,而且提供一种方便的手段,增加或修改类的功能
若要启用实验性的装饰器特性,你必须在命令行
或 tsconfig.json
里启用编译器
选项
启用的名字叫experimentalDecorators
装饰器
装饰器是一种特殊类型的声明,它能够被附加到类声明、方法、访问符、属性或者参数上
通过@
语法糖实现
使用方法:对于这个的实现我认为就是定义好了之后直接盖在你想对其使用目标的头顶上
- 以下两个代码块的watcher都是不支持传参的
const watcher:ClassDecorator = (target:Function)=>{ console.log(target) } @watcher//通过@去使用,会回传一个构造函数,也就是target class A{ } //通过ts-node xxx打印出来的结果为[class A]
知识点复习:
prototype 对象是实现面向对象的一个重要机制。每个函数也是一个对象,它们对应的类就是 function,每个函数对象都具有一个子对象 prototype。
Prototype 表示了该函数的原型,prototype 表示了一个类的属性的集合。当通过 new 来生成一个类的对象时,prototype 对象的属性就会成为实例化对象的属性。
const watcher:ClassDecorator = (target:Function)=>{ target.prototype.getName = <T>(name:T):T =>{ return name } } @watcher class A{ } let a = new A() a.getName()//会报类型"A"上不存在属性"getName" //(<any>a).getName()//我们将其断言成any类型 console.log((<any>a).getName("小满深夜骑单车"))//对其进行使用,输出 小满深夜骑单车 @watcher class B{ } let b = new B() console.log(b.getname('666'))//也是可以的
装饰器工厂
- 支持传参的写法
我认为其实就是多了一层壳,这层壳用来接收@watcher的参数。里面return的那一层再用来接收class A这个构造器
其实也就是一个高阶函数 外层的函数接受值 里层的函数最终接受类的构造函数
const watcher = (name=string):ClassDecorator =>{ return (target:Function) =>{ target.prototype.getNames = <T>(name:string):T =>{ return name } target.prototype.getOptions = (): string => { return name } } @watcher("小余的笔记") class A{ } let a = new A() console.log((<any>a).getNames())//返回 小余的笔记
装饰器组合
就是可以使用多个装饰器
//装饰器组合组合 const watcher = (name:string):ClassDecorator =>{ return (target:Function) =>{ target.prototype.getName = ()=>{ return name } } } const log:ClassDecorator = (target:Function) =>{ target.prototype.a = 213 } @log @watcher('小满') class A{ } const watcher = (name: string): ClassDecorator => { return (target: Function) => { target.prototype.getParams = <T>(params: T): T => { return params } target.prototype.getOptions = (): string => { return name } } } const watcher2 = (name: string): ClassDecorator => { return (target: Function) => { target.prototype.getNames = ():string => { return name } } } @watcher2('name2') @watcher('name') class A { constructor() { } } const a = new A(); console.log((a as any).getOptions()); console.log((a as any).getNames());
方法装饰器
返回三个参数
- 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
- 成员的名字。
- 成员的属性描述符。
相当于抽离出来,在类中引用进去,这样可以在不同的类中引用
[ {}, 'setParasm', { value: [Function: setParasm], writable: true, enumerable: false, configurable: true } ] const met:MethodDecorator = (...args) => { console.log(args); } class A { constructor() { } @met getName ():string { return '小满' } } const a = new A();
属性装饰器
返回两个参数
- 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
- 属性的名字。
[ {}, 'name', undefined ] const met:PropertyDecorator = (...args) => { console.log(args); } class A { @met name:string constructor() { } } const a = new A();
参数装饰器
返回三个参数
- 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
- 成员的名字。
- 参数在函数参数列表中的索引。
[ {}, 'setParasm', 0 ] const met:ParameterDecorator = (...args) => { console.log(args); } class A { constructor() { } setParasm (@met name:string = '213') { } } const a = new A();
Rollup构建TS项目(TS -- 21)
由于我使用的是vite打包工具,那这个视频是属于过一遍的程度,本章节内容将直接把小满在CSDN的文章copy过来
Rollup 构建 TS 项目
安装依赖
- 全局安装 rollup npm install rollup-g
- 安装 TypeScript npm install typescript -D
- 安装 TypeScript 转换器 npm install rollup-plugin-typescript2 -D
- 安装代码压缩插件 npm install rollup-plugin-terser -D
- 安装 rollupweb 服务 npm install rollup-plugin-serve -D
- 安装热更新 npm install rollup-plugin-livereload -D
- 引入外部依赖 npm install rollup-plugin-node-resolve -D
- 安装配置环境变量用来区分本地和生产 npm install cross-env -D
- 替换环境变量给浏览器使用 npm install rollup-plugin-replace -D
配置 json 文件
npm init -y { "name": "rollupTs", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "cross-env NODE_ENV=development rollup -c -w", "build":"cross-env NODE_ENV=produaction rollup -c" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "cross-env": "^7.0.3", "rollup-plugin-livereload": "^2.0.5", "rollup-plugin-node-resolve": "^5.2.0", "rollup-plugin-replace": "^2.2.0", "rollup-plugin-serve": "^1.1.0", "rollup-plugin-terser": "^7.0.2", "rollup-plugin-typescript2": "^0.31.1", "typescript": "^4.5.5" } }
配置 rollup 文件
console.log(process.env); import ts from 'rollup-plugin-typescript2' import path from 'path' import serve from 'rollup-plugin-serve' import livereload from 'rollup-plugin-livereload' import { terser } from 'rollup-plugin-terser' import resolve from 'rollup-plugin-node-resolve' import repacle from 'rollup-plugin-replace' const isDev = () => { return process.env.NODE_ENV === 'development' } export default { input: "./src/main.ts", output: { file: path.resolve(__dirname, './lib/index.js'), format: "umd", sourcemap: true }, plugins: [ ts(), terser({ compress: { drop_console: !isDev() } }), repacle({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) }), resolve(['.js', '.ts']), isDev() && livereload(), isDev() && serve({ open: true, openPage: "/public/index.html" }) ] }
配置 tsconfig.json
{ "compilerOptions": { /* Visit https://aka.ms/tsconfig.json to read more about this file */ /* Projects */ // "incremental": true, /* Enable incremental compilation */ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ "target": "es5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ /* Modules */ "module": "ES2015", /* Specify what module code is generated. */ // "rootDir": "./", /* Specify the root folder within your source files. */ // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "resolveJsonModule": true, /* Enable importing .json files */ // "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */ /* JavaScript Support */ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ /* Emit */ // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ // "declarationMap": true, /* Create sourcemaps for d.ts files. */ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ // "outDir": "./", /* Specify an output folder for all emitted files. */ // "removeComments": true, /* Disable emitting comments. */ // "noEmit": true, /* Disable emitting files from a compilation. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ // "newLine": "crlf", /* Set the newline character for emitting files. */ // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ /* Interop Constraints */ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ /* Type Checking */ "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ "skipLibCheck": true /* Skip type checking all .d.ts files. */ } }
npm run dev 启动就可以尽情的玩耍了