joken-前端工程师

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::

//interface 定义对象结构测试
interface abc {
  a: string, //基本数据类型声明都是小写开头
  b: number,
  c?: [string] //定义字符类型的数组
  cc?: Array<string>, //Array 是泛型类,用于创建数组对象
  f?: Object,
  n?: unknown,
  i?: any,
  x?: never,
  p?: undefined,
  p2?: null,
}

let myabc: abc = {
  a: "232342",
  b: 32421423,
  f: {}, //对象定义
}


interface cbd extends abc {
  alert: Function
};

// class用来实现抽象接口的具体行为
class mycls implements cbd {
  public a: string;
  public b: number;
  public static c: number = 2342343234;
  constructor() {
    this.a = "sykdfjsldfsdf"
    this.b = 23424234
    console.log(this.b, "vsslkdjfskfsdfkjsl")
  }
  alert() {
    console.log(this.b, "alert")
  }

  //protected 可以让子类访问到,但是实例不能访问
  protected alert2() {
    console.log("fathe,s alert2")
  }

  static fn1() {
    console.log(this.c, "slkfjslkfjslkdf")
  }
  static fn2() {
    console.log("测试super能不能调用到")
  }
}


class myclsChild extends mycls {
  constructor() {
    super() //相应于继承父类的显式私有属性,也就是this call过来,实际上就是执行了一遍构造函数,所以子类this就有父类this上的东西了
  }
  myalert() {
    //因为上面执行了super(),所以继承了父类的this下的显式属性
    console.log(this.a, "myalert")
  }

  myalert2() {
    super.alert2() //说明super是调用到了父类的原型prototype 属性而已,所以实际上super指向父类构造函数。
    //super.fn2() //语法报错,说明不能调用到父类的静态属性
  }

}

let childDemo = new myclsChild;
childDemo.alert()
childDemo.myalert()
childDemo.myalert2()


console.log("test")
mycls.fn1()

interface result {
  msg: string,
  code: number,
  data: any
}

//type 定义数据类型测试
type ddd = abc & {
  d: result
}

let dddDemo: ddd = {
  a: "ksjflksdfs",
  b: 23423423434,
  d: {
    msg: "成功",
    code: 0,
    data: {}
  }
}

console.log(dddDemo, "dddDemo")


interface eee extends ddd {

}

//interface接口用来描述对象结构
let myobj1: eee = {
  a: '234234242',
  b: 234234234,
  d: {
    msg: "成功",
    code: 0,
    data: {}
  }
}

console.log(myobj1, "myobj1")

enum RouterSource {
  Frontend = 'frontend',
  Backend = 'backend'
}

enum myenum {
  FALSE = 0,
  TRUE = 1
} //说明枚举也是用来限定数据范围


let enum12: myenum = 0;
console.log(enum12, "enum12")



function myfanxing<T>(a: T): Array<T> {
  let abc: T = a;
  return [abc]
}

let mmmm: unknown; //unknown和any的区别是any具体使用时不用类型断言,unknown具体使用的时候需要类型断言

mmmm = <string>"slkfjsdljsdf" //类型断言

let uuu = myfanxing<string>(mmmm as string) //类型断言

console.log(uuu, "uuu")


enum mutation_names {
  GET_LIST = 'GET_LIST',
  UP_FORM = 'UP_FORM',
}

interface MyState {
  lists: Array<any>,
  name: String,
  form: Object
}

//目前对下面代码的理解,是以函数作为key,具体的对象需要实现接口定义的结构
interface Mutations<S = MyState> {
  [mutation_names.GET_LIST](state: S, payload: Array<any>): void,
  [mutation_names.UP_FORM](state: S, payload: Object): void,
}

const mutations: Mutations<MyState> = {
  [mutation_names.GET_LIST](state: MyState, payload: Array<any>) {
    state.lists = payload;
  },
  [mutation_names.UP_FORM](state: MyState, payload: Object) {
    state.form = payload;
  }
}

//定义一个函数的结构
interface fnInterface {
  (a: string): void
}

const demoFn: fnInterface = (a: string) => {
  console.log('demoFn')
}

demoFn('234234')

//定义一个对象下各函数属性的结构
interface fnInterface2 {
  ['fn1'](a: string): void,
  ['fn2'](a: string): void
}

const fnCcc: fnInterface2 = {
  fn1: function (a: string) {
    console.log(a, "fn1===")
  },
  fn2: function (a: string) {

  }
}

fnCcc.fn1('sdfksjdfkjsdf')



//数组声明方式测试
let abc: string[] = ['sdlfjslfjslfd']

console.log(abc, "abc")

let abc2: [string] = ['sfjlskjflskdf']

console.log(abc2, "abc2")

let abc3: Array<string> = ['sdflksjdlfksjfd']

console.log(abc3, "abc3")


interface mykey {
  a: string,
  b: number
}

type mykeyType = keyof mykey // a | b 所以mykeyType类型的数值只能是 a|b

let mykeyDemo: mykeyType = 'a'
// let mykeyDemo: mykeyType = 'b'

console.log(mykeyDemo, "mykeyDemo")

interface mykey2 {
  a: string,
  b: number,
  c: boolean
}

type mykey2Type = keyof { [x: string]: mykey2 } //string | number

// let mykey2Demo: mykey2Type = false //报错,说明keyof 读取的是对象的key,不是对象的值

let mykey2Demo: mykey2Type = 1

console.log(mykey2Demo, "mykey2Demo")
console.log(typeof mykey2Demo, "mykey2Demo") //number


enum uii {
  a = 'a',
  b = "b"
}

type uiiType = keyof typeof uii; //枚举enum方式

let uiiDemo: uiiType = "a"

console.log(uiiDemo, "uiiDemo")


/*修饰器测试开始*/


function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {  //函数修饰器需要声明这3个参数
  const originalMethod = descriptor.value; //目标函数获取

  descriptor.value = function (...args: any[]) { //重写目标方法,也就是add
    console.log(`调用 ${propertyKey},参数为: ${JSON.stringify(args)}`);
    const result = originalMethod.apply(this, args);
    console.log(`方法 ${propertyKey} 返回值为: ${JSON.stringify(result)}`);
    return result;
  };

  return descriptor;
}

class Test {
  @log
  add(a: number, b: number) {
    return a + b;
  }
}

const test = new Test();
console.log(test.add(2, 3)); // 会打印出参数2,3和返回值5





interface myk {
  abc?: string, //加问号可以兼容隐式属性
  alert: Function
} //为什么加了这个接口,ccm才能打印出abc呢

function mydecorate(target: any) {//class 修饰器只有一个参数 target
  console.log(target, "target")
  target.name = "ldsfjlskdfjskldf"
  target.prototype.abc = "slfjslfjslkf" //目标class mykkk 的原型增加属性abc
}

@mydecorate
class mykkk {
  constructor() {
  }
  alert() {

  }
}

let ccm: myk = new mykkk();

console.log(ccm.abc, "xxx")

console.log(mykkk.name, "name")


const addSex = (sex: string): ClassDecorator => {
  return (target: any) => {
    target.prototype.sex = "slfjlskfjsklf"
    target.prototype.from = "slfjlskfjsklf"

    target.prototype.alert = () => {
      console.log("99999")
    }
    target.prototype.from = "kdfjlskkf"
  }
}

@addSex('女')
class Person {
  name: string = ''   //这里声明属性是增加到实例对象的显式属性中,也就是this下的属性,而不是prototype中
  age: number = 0


  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
  alert() {
    console.log("88888")
  }
  alert2() {
  }
}

interface P {
  name: string
  age: number
  sex?: string
  from?: string   //加问号可以兼容实例隐式声明的属性
  alert: Function,
  alert2: Function,
}

const p: P = new Person('张三', 18)
console.log(p.sex) // 女
console.log(p.from) // 女
p.alert()
p.alert2()


/*修饰器测试结束*/


/** 泛型 和 keyof测试 */
// 泛型只能用extends 约束
function myiii<T extends object, K extends keyof T>(obj: T, key: K) {
  return obj[key]

}

myiii({
  a: 'sdflksjdlfksjf'
}, 'a')


type iabc = {
  a: number,
  b: string
}

type icbd = {
  [k in keyof iabc]: string
}

let icbd_demo: icbd = {
  a: 'sdfsdf',
  b: 'sldfksjdfs'
}

console.log(icbd_demo, "icbd_demo")

/** 内置的工具类型测试 */
interface uaaa {
  a: string,
  b: number
}

//工具类型Pick使用,Pick选择类型中的属性
type uajjj=Pick<uaaa, 'a'> //从uaaa中��选属性a>


let uajjjDemo: uajjj = {
  a:'sdfsdf'
}

type myuaaa = Partial<uaaa> //给每个属性加上问号

let myudemo: myuaaa = {
  a: 'sdlfksjlfsf'
}

console.log(myudemo)

type myu2 = Omit<uaaa, 'b'> //排除属性

let myudemo2: myu2 = {
  a: 'sdlfkjsfd'
}

type myu3 = Record<'a' | 'b', string | number> //键值类型生成

let myudemo3: myu3 = {
  a: 'sdflksjf',
  b: 2342342143
}

type myu4 = Exclude<string | number, number> //排除类型

let myudemo4: myu4 = "sldfjsdljflfs"


//声明一个函数类型
type funAtype = {
  (a: string, b: number): number
}

// 函数的数据类型规范方式
let funAdemo: funAtype = (a: string, b: number) => {
  return b
}


let cccd: number = funAdemo("ssdfsdf", 23423)

console.log(cccd, "cccd")

//泛型的使用方式案例
function funAdemo2<T>(a: string, b: T): T {
  return b
}

let abcd: string = funAdemo2<string>("sdfjsdf", "skfjskf")

console.log(abcd, "abcd")

//ts函数声明方式2
interface myfn {
  (a: string, b: number): number
}

let myfndemo: myfn = (a: string, b: number) => {
  return b
}

// ts泛型使用案例
interface myfn2 {
  <T>(a: string, b: T): T
}

let myfn2demo: myfn2 = (a, b) => {
  return b
}
//这里泛型注入
myfn2demo<number>("sdfsdf", 234234)

//Record 使用案例
interface myInterface1 {
  a: string,
  b: string
}
let myrecord: Record<string, myInterface1> = {
  "abc": {
    a: "sdfsdf",
    b: "sdfsdf"
  },
  "cbd": {
    a: "sdfsdf",
    b: "sdfsdf"
  }
}


type mytype1 = "a" | "b" | "c"

let myrecord2: Record<mytype1, myInterface1>

myrecord2 = {
  a: {
    a: "sdfsdf",
    b: "sdfsdf"
  },
  b: {
    a: "sdfsdf",
    b: "sdfsdf"
  },
  c: {
    a: "sdfsdf",
    b: "sdfsdf"
  }
}

type mytype2 = "a" | "b" | "c"

interface mytypeInterface {
  a: string,
  b: string
}

let myrecord3: Record<keyof mytypeInterface, string>

myrecord3 = {
  a: "sdfsdf",
  b: "sdfsdf"
}


interface CatInfo {
  age: number;
  breed: string;
}

type CatName = "mincat" | "licat" | "mordred";

const cats: Record<CatName, CatInfo> = {
  mincat: { age: 10, breed: "小猫er" },
  licat: { age: 5, breed: "李猫er" },
  mordred: { age: 16, breed: "无名猫er" },
};

console.log(cats.mincat, "record_demo234234");


let mycats: Record<string, number> = {
  a: 234242
}

console.log(mycats, "mycats")


type abcd_skdfjskdf = "a" | "b" | "c" | "d" | "e";

type myobjInterface = {
  [key in abcd_skdfjskdf]: string
}


let myobj: myobjInterface = {
  a: "sdfsdf",
  b: "sdfsdf",
  c: "sdfsdf",
  d: "sdfsdf",
  e: "sdfsdf"
}

// type kkkk=keyof myobj //报错 ,说明keyof只能用于类型,不能用于值,和typeof相反

type kkkk=keyof myobjInterface //正确,keyof 一般用于interface类型的key获取


type myobjType = typeof myobj



class C {

  x = 0;

  y = 0;

}


//返回构造函数的的类型,typeof C 是一个函数类型,再InstanceType获取函数类型的构造函数类型
type T0 = InstanceType<typeof C>;

//说明class的类型,和class的实例类型不同,实例类型用于创建实例的类型约束
let uuui: T0 = new C();

console.log(uuui, "uuui")


type uucbd=ReturnType<()=>string> //ReturnType获取函数的返回类型
type uucbd2=ReturnType<()=>void> //ReturnType获取函数的返回类型


// typeof uucbd   //报错,因为typeof只能用于具体的值,不能用于类型


type mydom=Element //Element dom类型,一切dom基类

type mydom2=HTMLElement

type mouseEvent=MouseEvent



// keyof 针对类型而不是数据,T代表数据类型泛型
function myibc<T>(obj:T,key:keyof T){
  return obj[key]
}

//定义 对象的一种方式
type objType={
  [k:string]:any
}

const obj677:objType={
  name:"sdkjfskfjsdf",
  place:"sdlfjlsfdj"
}

const getKeyValue=myibc<objType>(obj677,'name')

console.log(getKeyValue,"getKeyValue")



















posted on 2024-05-29 16:04  joken1310  阅读(39)  评论(0编辑  收藏  举报