TypeScript-类、继承、接口、泛型、tsconfig
一、类
何为类?简而言之就是程序之中所有的操作都需要通过对象来完成。
class Person {
// 在属性前使用 static 关键字,可以定义静态属性(类属性),不需要创建对象就可以使用 实例对象没有静态属性
static age: number = 18;
// 实例属性 readonly表示只读属性,不能修改
// readonly name: string = "孙悟空";
name = "孙悟空";
// 定义方法 加上static 变成静态方法
sayHello() {
console.log("大家好");
}
}
const per = new Person();
console.log("per: ", per);
console.log(Person.age);
// console.log(per.age); 实例对象没有静态属性
console.log(per.name);
// per.name = "齐天大圣";
console.log(per.name);
// 方法
per.sayHello();
// Person.sayHello();
1.1 构造函数
在实例化一个类的时候,会自动调用该方法。
class Dog {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
bark() {
console.log("汪汪汪");
}
}
const dog1 = new Dog("阿喵", 9);
const dog2 = new Dog("阿呆", 6);
console.log(dog1);
console.log(dog2);
1.2 继承
作用是:共享父类的属性和方法
(function () {
// 定义公共类
class Animal {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
sayHello() {
console.log("动物在叫");
}
}
// 使用继承后,子类中将拥有父类的所有属性和方法
class Dog extends Animal {
run() {
console.log(`${this.name}在跑~~~`);
}
// 子类覆盖父类的方法 => 重写父类方法
sayHello() {
console.log("汪汪汪");
}
}
class Cat extends Animal {
sayHello() {
console.log("喵喵喵");
}
}
const dog = new Dog("阿呆", 8);
const cat = new Cat("阿喵", 3);
console.log("cat: ", cat);
cat.sayHello();
console.log("dog: ", dog);
dog.sayHello();
dog.run();
})();
1.3 super 关键字
可通过super关键字调用父类的方法。
// super 表示当前类的父类
(function () {
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
sayHello() {
console.log("大家好");
}
}
class Dog extends Animal {
age: number;
constructor(name: string, age: number) {
// 如果在子类中写了构造函数,相当于重写了父类的构造函数,此时需要对父类的构造函数进行调用
super(name); // 相应的参数也要传入进去
this.age = age;
}
sayHello() {
// super 表示当前类的父类
super.sayHello();
}
}
const dog = new Dog("旺财", 3);
dog.sayHello();
})();
1.4 抽象类与抽象方法
- 抽象类:即一种专门被其他类继承的类,生下来就是用来给别人继承的(即抽象类是父类),而且在抽象类当中可以添加抽象方法
- 抽象方法:没有方法体的方法,子类必须实现父类的抽象方法
(function () {
/**
* 以 abstract 开头的是抽象类,和其他类区别是:
* 1.不能被创建实例
* 2.抽象类可以添加抽象方法
*/
abstract class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
/**
* abstract 定义一个抽象方法
* 1.没有方法体
* 2.抽象方法只能定义在抽象类中
* 3.子类必须对抽象方法进行重写
*/
abstract sayHello(): void;
}
class Dog extends Animal {
sayHello() {
// super 表示当前类的父类
console.log("汪汪汪~");
}
}
// 非抽象类“Cat”不会实现继承自“Animal”类的抽象成员“sayHello”。
class Cat extends Animal {
sayHello() {
console.log("喵喵喵~");
}
}
const dog = new Dog("旺财");
const cat = new Cat("阿喵");
dog.sayHello();
// const an = new Animal() // 报错:无法创建抽象类的实例。
})();
二、接口
接口就是一组规范
接口与抽象类的区别:
- 接口:
- 都是抽象方法
- 属性不能有值,只定义属性类型
- interface定义 implements 实现接口
- 抽象类:
- 可以有抽象方法,也可以有普通方法
- class定义 extends 实现继承
(function () {
// type 描述一个对象的类型
type myType = {
name: string;
age: number;
};
/* 类型声明不可重复声明 */
// type myType = {
// name: string;
// age: number;
// };
/**
* 接口:用来定义一个类的结构
* 1.用来定义一个类中,应该包含那些属性和方法
* 2.同时也可以当成类型声明去使用
*/
interface myInterface {
name: string;
age: number;
}
/* 接口可以重复声明 */
interface myInterface {
gender: string;
}
const obj: myInterface = {
name: "sss",
age: 111,
gender: "男",
};
/**
* 接口可以在定义类的时候去限制类的值
* 1.接口中的所有属性都不能有实际的值 属性不能有值,方法不能有方法体
* 2.接口只定义对象的结构,而不考虑实际的值。
* 3.接口中所有的方法都是抽象方法
*/
interface myInter {
name: string;
sayHello(): void;
}
// 实现接口 => 使类满足接口的要求
class MyClass implements myInter {
name: string;
constructor(name: string) {
this.name = name;
}
sayHello(): void {
console.log("大家好");
}
}
})();
三、get set 及 public protected private
3.1 get And set
如需使用 getter、setter,TS中已帮我们内置了关键字 get、set 可直接跟上属性名,即可像正常对象的属性一样读取或设置该属性值。
(function () {
class Person {
// TS可以在属性前添加修饰符
/**
* public 公共属性,可以在任意位置访问或修改 默认值,包括子类和实例
* protected 受保护的属性,只能在当前类和当前类的子类中使用,不能在实例上访问
* private 私有属性,只能在类内部访问或修改,不能在子类中访问
*/
private _name: string;
private _age: number;
constructor(name: string, age: number) {
this._name = name;
this._age = age;
}
// 普通做法
// getName() {
// return this.name;
// }
// setName(value: string) {
// this.name = value;
// }
// getAge() {
// return this.age;
// }
// setAge(value: number) {
// if (value >= 0) {
// this.age = value;
// } else {
// throw new Error("年龄必须大于等于0");
// }
// }
// TS中做法
get name(): string {
return this._name;
}
set name(value: string) {
this._name = value;
}
get age(): number {
return this._age;
}
set age(value: number) {
if (value >= 0) {
this._age = value;
} else {
throw new Error("年龄必须大于等于0");
}
}
}
const person = new Person("孙悟空", 18);
// 普通做法
// console.log(person.getName());
// person.setName("猪八戒");
// console.log(person.getName());
// person.setAge(-5);
// console.log(person);
// TS做法
console.log(person.name);
person.name = "猪八戒";
console.log(person.name);
// person.age = -5;
console.log(person.age);
})();
3.2 public protected private
class A {
public name: string;
protected age: number;
private num: number;
constructor(name: string, num: number, age: number) {
this.name = name;
this.age = age;
this.num = num;
}
}
class B extends A {
test() {
console.log(this.name);
console.log(this.age);
// console.log(this.num); // 属性“num”为私有属性,只能在类“A”中访问
}
}
const b = new B("阿喵", 1, 3);
console.log(b.name);
// console.log(b.age); // 属性“age”受保护,只能在类“A”及其子类中访问。
// console.log(b.num); // 属性“num”为私有属性,只能在类“A”中访问。
/**
* 语法糖,简写了属性的定义及赋值
*/
class C {
// 可以直接将属性定义在构造函数中
constructor(public name: string, protected age: number) {}
}
const c = new C("阿呆", 8);
console.log(c);
四、泛型
在定义函数或者类时,如果遇到类型不明确的,就可以使用泛型。
泛型就是一个不确定的类型。
在我们类型不明确的时候,整一个变量,用这个变量来表示类型(泛型)
/**
* 在定义函数或者类时,如果遇到类型不明确的,就可以使用泛型
* => 泛型就是一个不确定的类型。
* 泛型的作用就是,在我们类型不明确的时候,整一个变量,用这个变量来表示类型(泛型)
*/
// 这个T是什么类型呢?谁都不知道,只有在函数执行的时候才能确定
// 能体现出传入的参数类型,与返回的参数类型是同一类型
function fn<T>(a: T): T {
return a;
}
// 直接调用具有泛型的函数
let result = fn(2); // TS会自动推断出参数类型
let result2 = fn<string>("hello"); // 手动指定
console.log("result: ", result);
console.log("result2: ", result2);
function fn2<T, K>(a: T, b: K): T {
console.log(b);
return a;
}
fn2<number, string>(123, "hello");
interface Inter {
length: number;
}
// T extends Inter 表示泛型T必须实现Inter接口,即必须是Inter实现类(子类)
function fn3<T extends Inter>(a: T): number {
return a.length;
}
fn3("123");
// fn3(456); // 类型“number”的参数不能赋给类型“Inter”的参数。
fn3({ name: "good", length: 5 });
fn3([1, 2, 3, 4, 5, 6, 7, 8, 9]);
class MyClass<T> {
name: T;
constructor(name: T) {
this.name = name;
}
}
const mc = new MyClass<string>("孙悟空");
五、tsconfig.js 配置文件解析
{
// include 包含
// 一个(*)任意文件,两个(*)任意目录
"include": ["./src/**/*"],
// exclude 不包含 默认值:["node_modules","bower_components","jspm_packages"]
// "exclude": ["./src/hello/**/*"],
// 定义被继承的配置文件
// "extends": "",
// compilerOptions 编译选项
"compilerOptions": {
// 打包代码生成的格式
// 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'es2021', 'esnext'
"target": "ES3",
// 支持的模块化格式 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'es2020', 'esnext'.
"module": "system",
// 用来指定项目中要使用的库,为空的话则没有document这些代码提示,以此区分代码提示是在浏览器环境还是Node
// 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'es2021', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'webworker.iterable', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asyncgenerator', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.object', 'es2019.string', 'es2019.symbol', 'es2020.bigint', 'es2020.promise', 'es2020.sharedmemory', 'es2020.string', 'es2020.symbol.wellknown', 'es2020.intl', 'es2021.promise', 'es2021.string', 'es2021.weakref', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl', 'esnext.bigint', 'esnext.string', 'esnext.promise', 'esnext.weakref'.
// "lib": ['a'],
// 指定输出文件目录
"outDir": "./dist",
// 全局作用域中的代码会合并到同一个文件中
"outFile": "./dist/main.js",
// 是否对 JS 文件进行编译:default:false
"allowJs": true,
// 检查 JS 代码是否符合 TS语法规范。检查强类型
"checkJs": true,
// 是否移除注释
"removeComments": true,
// 不生成编译后的文件 default:false
"noEmit": false,
// 有错误不生成编译文件 default:false
"noEmitOnError": true,
// strict 所有严格检查的总开关 default:false
"strict": true,
// 编译后的文件是否使用严格模式。 default:false
"alwaysStrict": true,
// 不允许隐式 any 类型 default:false(即默认可以使用 隐式 any)
"noImplicitAny": false,
// 不允许不明确类型的 this
"noImplicitThis": false,
// 严格的检查空值
"strictNullChecks": true,
}
}
转载请注明作者和出处,并添加本页链接。
原文链接:
//www.v2ci.com/32.html