一,接口(interface)
概述:描述对象的行为和形状
例子
javascript
interface IUser{
id:number
readonly name: string //只读
// name: string
age?: number //可选
// 索引签名
[aaa: string] : unknown
//函数类型
say(name: string ,age: number): void
}
const user: IUser = {
id:0,
name:'张三',
age:19,
gender:'man',
say(name: string, age: number){
}
}
es5
const user = {
id: 0,
name: '张三',
age: 19,
gender: 'man',
say(name, age) {
}
};
接口继承类
javascript
// 人类
class People implements IUser{
id: number = 0
name: string = '匿名'
age:number = -1
sex: string = 'unknown'
say(name: string, age: number): void {
console.log('hello');
}
constructor(name:string){
this.name = name
}
[aaa: string]: unknown
}
// 动物类
class Animal {
id:number
name:string
constructor(id:number,name:string){
this.id = id
this.name = name
}
}
// 接口继承动物类
interface People1 extends Animal{
age: number
}
const user22: People1 = {
id:0,
name:'zz',
age:666
}
es5
// 人类
class People {
say(name, age) {
console.log('hello');
}
constructor(name) {
this.id = 0;
this.name = '匿名';
this.age = -1;
this.sex = 'unknown';
this.name = name;
}
}
// 动物类
class Animal {
constructor(id, name) {
this.id = id;
this.name = name;
}
}
const user22 = {
id: 0,
name: 'zz',
age: 666
};
class和interface的异同点
1,都可以作为类型
2,class不仅可以有类型,还可以有值,interfance 只有类型
二,类型别名(type)
概述:很多场景下和interface是一样的,但是类型别名适用的场景更广泛,,它不会生成新的类型,但是类型别名的语义性(可读性)不高,所以官方推荐优先使用interface
类型别名和接口的区别:
1,接口可以继承和实例,类型别名不行
2,接口会创建一个新的类型,类型别名不会
3,接口只能定义对象类型,类型定义的别名还可以定义其他类型
javascript
type TAge = string | number
const age: TAge = '12'
type TUser = {
id:number
name : string
age: number
}
const user1: TUser={
id:0,
name:'狄仁杰',
age:12
}
const user222: TUser1={
// id:0,
name:'狄仁杰',
age:12
}
interface TUser1{
name:string
age:number
}
es5
const age = '12';
const user1 = {
id: 0,
name: '狄仁杰',
age: 12
};
const user222 = {
// id:0,
name: '狄仁杰',
age: 12
};
三,泛型
概念:声明一个类型变量,声明一未来知道的具体类型的变量,
作用:实现类型的复用
javascript
function getData<T>( msg: T): T{
// var a : T // 泛型可以在函数内部任意地方使用
return msg
}
// 这里的T会是字符串类型,也会是数值型
console.log('狄仁杰'); //字符串
console.log(11); //数值
es5
function getData(msg) {
// var a : T // 泛型可以在函数内部任意地方使用
return msg;
}
console.log('狄仁杰');
console.log(11);
四,装饰器
分类: 类装饰器,方法装饰器
类装饰器:本身是一个函数,返回一个函数
方法装饰器:将方法里传入的参数进行类型设定
类装饰器:
javascript
// 类装饰器
// 本身是一个函数 返回一个函数
function log(params:any){
console.log(params);
return(target:any)=>{
console.log(target);
}
}
es5
// 类装饰器
// 本身是一个函数 返回一个函数
function log(params) {
console.log(params);
return (target) => {
console.log(target);
};
}
方法装饰器:
javascript
// 方法装饰器
function log1(params:string,a:any,b:any,c:any){
console.log(params,a,b,c);
return(target: any ,name:any,descriptor:any,f:any)=>{
console.log('1111',target,name,descriptor);
}
}
@log('类装饰器传入的参数1')
class People1 {
name:string = '张三';
constructor(name:string){
console.log('构造函数');
this.name = name
}
@log('方法装饰器的参数') say():void{
console.log('hello');
}
}
const p1 = new People1('李世民')
console.log(p1.name);
es5
// 方法装饰器
function log1(params, a, b, c) {
console.log(params, a, b, c);
return (target, name, descriptor, f) => {
console.log('1111', target, name, descriptor);
};
}
let People1 = (() => {
let _classDecorators = [log('类装饰器传入的参数1')];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
let _instanceExtraInitializers = [];
let _say_decorators;
var People1 = _classThis = class {
constructor(name) {
this.name = (__runInitializers(this, _instanceExtraInitializers), '张三');
console.log('构造函数');
this.name = name;
}
say() {
console.log('hello');
}
};
__setFunctionName(_classThis, "People1");
(() => {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
_say_decorators = [log('方法装饰器的参数')];
__esDecorate(_classThis, null, _say_decorators, { kind: "method", name: "say", static: false, private: false, access: { has: obj => "say" in obj, get: obj => obj.say }, metadata: _metadata }, null, _instanceExtraInitializers);
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
People1 = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
__runInitializers(_classThis, _classExtraInitializers);
})();
return People1 = _classThis;
})();
const p1 = new People1('李世民');
console.log(p1.name);
五,类型守卫
概念:用于在运行时检查和缩小 any
类型或联合类型变量的可能类型集合
作用:有助于在处理不确定类型的变量时提高代码的类型安全性。
javascript
interface IUser{
name:string
age:number
sex:string
score:number
}
type TUser = keyof IUser // name | age | sex |score
const user2 : TUser = 'score'
es5
const user2 = 'score';
六,class类
概念:类(Class)是一种封装数据和行为的模板,它定义了一类对象的属性(成员变量)和方法(成员函数)。类可以被看作是创建对象的蓝图或模板,它描述了对象的内部状态(属性)和行为(方法)。
作用:有助于提高代码的可读性、可维护性和可重用性。
javascript
class Animal{
public type: string //任何地方都可以使用
private body: boolean = true //只有该类内部可以通过this使用
// 如果类里面的成员属性没有初始值,而是通过实例化的时候传入,此时需要使用constructor
// 如果类里面的成员属性有初始值,可以不用写constructor
constructor(type: string){
this.type = type
}
protected move(): string{
return `我是${this.type},我会动`
}
jump(): void{
console.log(this.move()); //protected修饰符,允许在父类
}
}
// 人类是动物类的子类/派生类,这里的动物类就是父类/基类/超类
class People extends Animal{
name: string
age: number = 13
set: string = '男'
constructor(name: string,type:string){
super(type)
this.name = name
}
run(): void{
//
// this.body
console.log(`我是${ this.name},我会跑`);
}
}
// 程序员类继承人类
class coder extends People{
name = 'li'
}
es5
"use strict";
class Animal {
// 如果类里面的成员属性没有初始值,而是通过实例化的时候传入,此时需要使用constructor
// 如果类里面的成员属性有初始值,可以不用写constructor
constructor(type) {
this.body = true; //只有该类内部可以通过this使用
this.type = type;
}
move() {
return `我是${this.type},我会动`;
}
jump() {
console.log(this.move()); //protected修饰符,允许在父类
}
}
// 人类是动物类的子类/派生类,这里的动物类就是父类/基类/超类
class People extends Animal {
constructor(name, type) {
super(type);
this.age = 13;
this.set = '男';
this.name = name;
}
run() {
//
// this.body
console.log(`我是${this.name},我会跑`);
}
}
// 程序员类继承人类
class coder extends People {
constructor() {
super(...arguments);
this.name = 'li';
}
}
const ai = new Animal('怕像动物');
// ai.move()
const p1 = new People('张三丰', '哺乳动物');
// p1.move()
七:工具类型
1partial (可选意思) 会将数据类型变为可选,接口如果同名则会自动合并
javascript
interface IUser2{
age:number
sex:string
}
interface IUser2{
id:number
name:string
}
es5
const u1 = {
id: 0,
name: "李四",
age: 12,
sex: '男'
};
八,命名空间
1,关键字:namespace 声明
2,使用:外面如果需要使用命名空间里的接口,那么就需要导出(export)想使用的,
单例模式也是命名空间
javascript
// js中的命名空间
// 单例模式其实就是给一些数据添加一个命名空间,方便统一维护管理
const o1 ={
name:'lis',
age:12,
say(){}
}
o1.say()
es5
// js中的命名空间
// 单例模式其实就是给一些数据添加一个命名空间,方便统一维护管理
const o1 = {
name: 'lis',
age: 12,
say() { }
};
使用命名空间:
javascript
// js中的命名空间
// 单例模式其实就是给一些数据添加一个命名空间,方便统一维护管理
const o1 ={
name:'lis',
age:12,
say(){}
}
o1.say()
// 命名空间 namespace 声明
// 外面如果需要使用命名空间里的接口,那么就需要导出想使用的,
namespace demo{
export interface IUser{
name:string
age:number
}
}
const u2 : demo.IUser = {
name:'zs',
age:12
}
es5
"use strict";
// js中的命名空间
// 单例模式其实就是给一些数据添加一个命名空间,方便统一维护管理
const o1 = {
name: 'lis',
age: 12,
say() { }
};
o1.say();
const u2 = {
name: 'zs',
age: 12
};