Typescript模块的导入导出与继承方式

Laura ·
更新时间:2024-11-10
· 1305 次阅读

目录

Typescript模块的导入导出与继承

导入测试

导出测试

TypeScript知识点整理

TS 和 JS 有什么差异

TS 数据类型

TS 中的类

TS 的访问修饰符

TS 中的接口 - interface

泛型

文件 .d.ts 的作用

const 和 readonly 的区别

枚举和常量枚举(const 枚举)的区别

TS 中的 interface 可以给 Function/Array/Class 做声明吗

TS 中如何枚举联合类型的 key

什么是抗变、双变、协变和逆变

TS 中同名的 interface 或者同名的 interface 和 class 可以合并吗

如何使 TS 项目引入并识别编译为 JS 的 npm 库包

TS 如何自动生成库包的声明文件

-?、-readonly

TS 是基于结构类型兼容

const 断言

type 和 interface 的区别

implements 与 extends 的区别

枚举和 object 的区别

never 和 void 的区别

unknown 和 any 的区别

如何在 window 扩展类型

元组越界问题

重写(override)和重载(overload)

Typescript模块的导入导出与继承

ModA.ts

export let x = 8888; export let print = function (x){console.log(x);};

ModB.ts

export let x = 8888; export let print = function (x){console.log(x);};

ModTest.ts

export * as B from "./ModB"; export {H,Hello}  from "./ModB.js"; export {Hello as exp}  from "./ModB.js"; 导入测试 //导出变量 export let HeadName = 'Nance'; export let MidName = 'Jone'; export let BothDate = '2020-12-20'; let [X,Y,Z]=[0,0,0]; export {X,Y,Z}; //导出函数 export function Add(a,b){return a+b;} function Multiply(x,y){return x * y;} export {Multiply}; function a1(a,b){return a+b;} function b1(a,b){return a-b;}; export {a1,b1};//导出多个函数 //函数别名形式导出 export {a1 as ADD_FUNC ,b1 as DEL_FUNC}; //默认导出,一个模块只能有一个默认导出,不管是类,方法或者是变量 //export default class a{};//默认导出类a后就不能再默认导出函数,或者默认导出变量 //export default function b(){}; let qq=0; export default qq; //默认导出不能使用 as 别名导出 导出测试 import {HeadName,MidName,BothDate,X,Y,Z,ADD_FUNC,DEL_FUNC,Add} from "./ExportEx"; export {ADD_FUNC,DEL_FUNC,Add as myAdd} from "./ExportEx";//从导入模块直接导出方法 console.log(HeadName,MidName,BothDate); console.log(X,Y,Z); console.log(ADD_FUNC(1,2),DEL_FUNC(3,4)); console.log(Add(5,6)); TypeScript知识点整理 TS 和 JS 有什么差异

JS:动态类型,运行时明确变量的类型,变量的类型由变量的值决定,并跟随值的改变而改变;直接运行在浏览器和 node.js 环境中;弱类型,数据类型可以被忽略的语言。一个变量可以赋不同数据类型的值。

TS:静态类型,声明时确定类型,之后不允许修改;编译运行,始终先编译成 JavaScript 再运行;强类型,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了。

TS 数据类型

基本数据类型:string、number、boolean

引用数据类型:数组(number[]、string[]、boolean[]、(number | string | boolean)[])、null、undefined、{ pname: string; page: number }、枚举、void、Object、断言

TS 中的类

类中的实例属性, 需要提前声明,,才能在 constructor 构造函数中进行实例属性的初始化。

存取器的操作:就像操作普通对象一样即可

set 方法:负责对内部的私有属性赋值.,同时可以达到对外部数据的拦截作用。

get 方法:负责对外提供私有属性的值。

TS 的访问修饰符

public:公共的

private:私有的,外部类不可访问

protected:受保护的,类的内部或子类可访问

readonly:只读的

TS 中的接口 - interface

interface 接口,主要描述对象结构,一个对象中应该有什么属性,赋值的时候需要符合接口规范。它主要针对的是对象结构,type关键字也可以描述对象, 除此之外,type 还可以描述基本类型,联合类型等。

// (newName: string) => void: 这就是类型, 对一个函数进行约束. // 利用接口对函数进行约束, 描述一个函数的结构, 有什么参数, 什么返回值. interface FunctionType {   (newName: string, newAge: number, test?: string): void; } let setMyName: FunctionType = function (   name: string,   age: number,   a?: string ): void {   console.log(name + age); }; setMyName("新名称", 100); // 利用接口定义类的结构, 对类中的属性和方法进行约束. interface AnimalType {   aname: string;   eat(n: string): void; } // implements 表示一个类要实现某个接口, 必须按照接口的要求, 实现这个类的内部结构. class Animal implements AnimalType {   aname: string;   constructor() {     this.aname = "鸭子";   }   eat(a: string): string {     return "123";   } } let ani = new Animal(); console.log(ani.eat("1")); 泛型

在定义函数function 或者 接口interface 或者 类型type 时,由我们传入指定类型,函数/接口/类型 内部都会根据这个类型做业务处理。简单的说,“泛型就是把类型当成参数”。

// 制作泛型接口, 用T来表示广泛的类型, 就看使用的时候, 传递的是什么类型. interface PType<T> {   p: T;   p1: T; } type PTypeOne<T> = {   p: T;   p1: T; }; let pp1: PTypeOne<string> = {   p: "123",   p1: "222", }; let pp2: PType<number> = {   p: 12,   p1: 22, }; let pp3: PType<number[]> = {   p: [1, 2, 3],   p1: [4, 5, 6], }; // 制作泛型函数 function getValue<T>(a: T, b: T): T {   return (a as any) + (b as any); } console.log(getValue<string>("10", "20")); console.log(getValue<number>(10, 20)); function getResult<T, Y>(a: T, b: Y): any {   return (a as any) + (b as any); } console.log(getResult<string, number>("10", 20)); 文件 .d.ts 的作用

全局声明公共的类型,所有的.ts文件默认从这个文件中查找类名名称,.ts不需要单独导入这个文件,.d.ts文件也不需要单独的导出某个类型。

// 对于联合类型比较长的情况,可以通过type关键字,给这个联合类型起个别名(相当于自定义了一种新类型)。重用的时候写起来方便。 type baseTypeArr = (number | string | boolean)[]; // number | string | boolean | number[]: 联合类型,表示当前这个变量,允许接收number/string/boolean/number[]这几个类型中的一个即可。 type baseType = number | string | boolean | number[]; // 对于初始值可能为null/undefined的类型,也使用联合类型约束 declare type dataType = string | undefined; declare type arrType = number[] | null; // declare 声明类型 namespace 命名空间 ,每个命名空间内都是独立作用域,其实就是将不同的类型放到各自的模块内,统一管理。 namespace HomeType {   type homeList = number | string; } declare namespace CateType {   type cateList = number | string; } declare namespace CartType {   type cartList = number | string; } // 自定义类型,叫People类型 // psex?: boolean 表示People类型中的psex属性可有可无 type People = {   page: number;   pname: string;   psex?: boolean | undefined; }; type CommonObject = {   // [propName: string | number]: string | number | boolean; // [propName: string] 接收任意key,且是字符串。   [propName: string | number]: any; // any:让一个变量可以是任意类型的值,被any标识的数据,ts会放弃对它的检查,而是直接通过编译,ts失效了。一定是在不确定类型/类型不统一是才使用any。 }; declare interface MyPeople {   pname: string;   page: number;   psex?: boolean; } const 和 readonly 的区别

const:用于变量,在运行时检查;使用 const 变量保存的数组,可以使用 push、pop 等方法。

readonly:用于属性,在编译时检查;使用Readonly Array<number>声明的数组不能使用push,pop等方法。

枚举和常量枚举(const 枚举)的区别

枚举会在编译时被编译成一个对象,可以当作对象使用。

const 枚举会在 TS 编译期间被删除,避免额外的性能消耗。

   // 普通枚举    enum Witcher {      Ciri = 'Queen',      Geralt = 'Geralt of Rivia'    }    function getGeraltMessage(arg: {[key: string]: string}): string {      return arg.Geralt    }    getGeraltMessage(Witcher) // Geralt of Rivia    // const枚举    const enum Witcher {      Ciri = 'Queen',      Geralt = 'Geralt of Rivia'    }    const witchers: Witcher[] = [Witcher.Ciri, Witcher.Geralt]    // 编译后    // const witchers = ['Queen', 'Geralt of Rivia'

   

TS 中的 interface 可以给 Function/Array/Class 做声明吗

可以

TS 中如何枚举联合类型的 key   type Name = { name: string }   type Age = { age: number }   type Union = Name | Age   type UnionKey<P> = P extends infer P ? keyof P : never   type T = UnionKey<Union> 什么是抗变、双变、协变和逆变

Covariant 协变,TS对象兼容性是协变,父类 <= 子类,是可以的。子类 <= 父类,错误。

Contravariant 逆变,禁用strictFunctionTypes编译,函数参数类型是逆变的,父类 <= 子类,是错误。子类 <= 父类,是可以的。

Bivariant 双向协变,函数参数的类型默认是双向协变的。父类 <= 子类,是可以的。子类 <= 父类,是可以的。

TS 中同名的 interface 或者同名的 interface 和 class 可以合并吗

interface 会合并

class 不可以合并

如何使 TS 项目引入并识别编译为 JS 的 npm 库包

npm install @types/xxxx

自己添加描述文件

TS 如何自动生成库包的声明文件

可以配置tsconfig.json文件中的declaration和outDir

1.declaration: true, 将会自动生成声明文件

2.outDir: ‘’, 指定目录

-?、-readonly

用于删除修饰符

type A = {     a: string;     b: number; } type B = {     [K in keyof A]?: A[K] } type C = {     [K in keyof B]-?: B[K] } type D = {     readonly [K in keyof A]: A[K] } type E = {     -readonly [K in keyof A]: A[K] } TS 是基于结构类型兼容

typescript的类型兼容是基于结构的,不是基于名义的。下面的代码在ts中是完全可以的,但在java等基于名义的语言则会抛错。

interface Named { name: string } class Person {   name: string } let p: Named // ok p = new Person() const 断言

const断言,typescript会为变量添加一个自身的字面量类型

对象字面量的属性,获得readonly的属性,成为只读属性

数组字面量成为readonly tuple只读元组

字面量类型不能被扩展(比如从hello类型到string类型)

// type '"hello"' let x = "hello" as const // type 'readonly [10, 20]' let y = [10, 20] as const // type '{ readonly text: "hello" }' let z = { text: "hello" } as const type 和 interface 的区别

type 侧重于直接定义类型,还可以给一个或多个类型起一个新名称(当变量用),interface 只能定义对象数据结构类型;

type 可以为基本类型、联合类型或元组甚至any等等赋值定义别名,interface 明显办不到;

interface 定义重名了会合并属性,type 办不到(会报错提醒 重复定义);

type 不支持继承。

implements 与 extends 的区别

extends, 子类会继承父类的所有属性和方法。

implements,使用 implements 关键字的类将需要实现需要实现的类的所有属性和方法。

枚举和 object 的区别

枚举可以通过枚举的名称,获取枚举的值。也可以通过枚举的值获取枚举的名称。

object 只能通过 key 获取 value。

数字枚举在不指定初始值的情况下,枚举值会从0开始递增。

虽然在运行时,枚举是一个真实存在的对象。但是使用 keyof 时的行为却和普通对象不一致。必须使用 keyof typeof 才可以获取枚举所有属性名。

never 和 void 的区别

never:表示永远不存在的类型。比如一个函数总是抛出错误,而没有返回值。或者一个函数内部有死循环,永远不会有返回值。函数的返回值就是 never 类型。

void:没有显示的返回值的函数返回值为 void 类型。如果一个变量为 void 类型,只能赋予undefined 或者 null。

unknown 和 any 的区别

unknown 类型和 any 类型类似。

与 any 类型不同的是,unknown 类型可以接受任意类型赋值,但是 unknown 类型赋值给其他类型前,必须被断言。

如何在 window 扩展类型   declare global {     interface Window {       myCustomFn: () => void;     }   } 元组越界问题 let aaa: [string, number] = ['aaa', 5]; // 添加时不会报错 aaa.push(6); // 打印整个元祖不会报错 console.log(aaa); // ['aaa',5,6]; // 打印添加的元素时会报错 console.log(aaa[2]); // error 重写(override)和重载(overload)

重写是指子类重写“继承”自父类中的方法 。虽然 TS 和 JAVA 相似,但是 TS 中的继承本质上还是 JS 的“继承”机制—原型链机制

重载是指为同一个函数提供多个类型定义

class Animal { speak(word: string): string { return '动作叫:' + word; } } class Cat extends Animal { speak(word: string): string { return '猫叫:' + word; } } let cat = new Cat(); console.log(cat.speak('hello')); /**--------------------------------------------**/ function double(val: number): number function double(val: string): string function double(val: any): any { if (typeof val == 'number') { return val * 2; } return val + val; } let r = double(1); console.log(r);

以上为个人经验,希望能给大家一个参考,也希望大家多多支持软件开发网。



继承 TypeScript

需要 登录 后方可回复, 如果你还没有账号请 注册新账号