TypeScript

39 阅读3分钟
// ts基础类型
let a : number = 1
let b : string = '1'
let c : boolean = true
let d : string[] = ['1', '2']
let d1 : Array<string> = ['1', '2']
let a1 : any = undefined
let b1 : unknown = null
function getName(): void{
 return undefined
}
function getNumber(a:number, b?:string):number{
    return 1
}
getNumber(1)
// 元祖
let e : [number, string] = [1, '2']
let f : [number, string?] = [1]
let g : [number, ...string[]] = [1, '2', '3']
// 枚举
const enum a11  { up, down, left = 5, right }
const enum a22 {up = 'up', down = 'down'}

// 字节约束
let h : '男' = '男'
let i : {name: string, age: number} = {name: '张三', age: 18 }
let j : {[key:string]: string} = {name: '李四', sex: '男'}
// 自定义类型
type shuzi = number
let k : shuzi = 1
type shuzizifuchuan = number | string
type sex = '男' | '女'
let l : shuzizifuchuan = '1'
type shuzizifuchuan1 = {name: string} & {age:number}
let m : shuzizifuchuan1 = {name: '成', age: 22 }
let n : sex = '男'
// 类  override 覆盖父类方法
class Pwrson {
    public name : string //公开的
    protected age : number // 受保护的
    private readonly sex : String // 私有的  readonly 只读的。不允许改变
    constructor(name: string, age:number, sex: string ){
        this.name = name
        this.age = age
        this.sex = sex
    }
    public speak():string{
        return `${this.name}今年${this.age},是一个${this.sex}神`
    }
}
const p1 = new Pwrson('程创', 18, '男')
console.log(p1.speak())
// 简写 子类继承父类时,如果没写构造函数会默认调用父类构造函数。写上构造函数需要显式调用super()
class Person {
    constructor(public name: string, protected age: number, private sex : string ){}
}
// 抽象类、无法被实例化, 给其他类做规则。 可以写抽象方法和具体方法。继承他必须实现抽象方法、 例如一个包裹抽象类。都有长宽高都有运费
// 用具体函数调用抽象方法、子类实现抽象方法后就可以直接调用具体函数。
// 在什么时候用抽象类? 提供通用接口、 提供基础实现 、确保关键实现、共享代码和逻辑、 约束子类行为
abstract class Package{
    // 构造方法
    constructor(public weight: number){}
    // 抽象方法
    abstract calculate():number
    // 具体方法  
    printPackage(){
        console.log(`包裹重量为${this.weight}kg,运费为:${this.calculate()}元`)
    }
}
// 继承抽象类
class StandardPackage extends Package {
    constructor(weight: number,public unitPrice : number){
        super(weight)
    }
    calculate(): number {  
        return this.weight * this.unitPrice
    }
}
const s1 = new StandardPackage(10, 20)
s1.printPackage()
// const p1 = new Package()
// 接口 接口是定义类、对象的结构, 是一种规范。不能包含任何实现。
// 和抽象类的区别。 抽象类可以具体做事。 接口不能具体做事。
// 接口可以用对象实现也可以用类型定义
// 接口在TS里很重要 。出场率最高!API返回往往都是对象。并且可以混合合并。
// 一个类只能继承一个抽象类。但是可以实现多个接口。extends anmial implements Ifly, Iswim
interface Iperson { // 定义类
    name: string
    age: number
    speak(n:number): void
}
class Person1 implements Iperson{
    constructor(public name: string, public age : number){}
    speak(n: number): void {
        console.log(`你好${n}。我叫${this.name},我今年${this.age}`);
    }
}
const person2 = new Person1('程创', 31)
person2.speak(1)
interface Iuser { // 定义对象
    name : String
    readonly gender: string // 只读属性
    age?: number
    run:(n:number) => void
}
const user: Iuser = {
    name : "张三",
    gender : '男',
    run(n) {
        console.log(`${this.name}奔跑了${n}米`)
    } 
}
user.run(200);
user.name = '李四'
user.run(200)
interface Icount{ // 定义函数
    (a:number, b:number):number
}
const count: Icount = (x, y) => {
    return x + y
}
// 接口可以继承接口
interface PersonInterFace {
    name: string // 姓名
    age: number // 年龄
}
interface studentInterface extends PersonInterFace {
    grade : string // 年纪
}
const stu:studentInterface = {
    name: '张三',
    age: 18,
    grade: '初二',
}
// 接口可混合定义,合并。 两个相同名称接口的定义会取并集。
interface per3 {
    name : string,
    age: number,
}
interface per3 {
    sex: string
}
const person3 : per3 = {
    name: '张三',
    age: 18,
    sex: '男'
}
// 泛型
// 泛型函数
function logData<T>(data:T){ // 单泛型
 console.log(data)
}
function log4g<T, U>(data1:T, data2:U){ // 多泛型
    console.log(data1, data2)
}
logData<number>(100)
logData('dsafd')
log4g<string, number>('hello', 666)
// 泛行接口  可以定义接口返回!! 
type JobInfo = {
    title: string;
    company: string;
}
interface PersonInterF1ace<T>{
    name: string,
    age: number,
    extraInfo: T
}
let p : PersonInterF1ace<JobInfo> = {
    name: 'tom',
    age: 18,
    extraInfo: {
        title: '报社',
        company: '齐鲁公司'
    }
}
// 泛行类
class Person11<T>{
    constructor(
        public name: string,
        public age: number,
        public extraInfo: T
    ){}
    speak(){
        console.log(`我叫${this.name},今年${this.age}岁了。`)
        console.log(this.extraInfo)
    }
}
const p22 = new Person11<number>('tom', 30, 250)

// 类型声明文件 .d.ts  为现有的js代码提供说明信息。一般大型第三方库都会提供。找到d.ts文件引入即可。

// 装饰器 return返回类。则会替换原本类,无返回则不替换
 const Demo = function (target : Function){
    console.log(target, 333)
    target.prototype.test1 = ()=>{
    console.log('hello, 12313')
    }
    target.prototype.test1();
    target.prototype.sex = '男'
    console.log(target.prototype, 444)
 }
@Demo
class test {
    name: string = '男'
    constructor(public age: number){}
    test1(){}
}
const test1 = new test(14)
console.log((test1 as any).sex, 66666);

test1.test1()

function test22(){
    const a = 11
    function b () {
        console.log('你好')
    }
    console.log('hello')
}
// 自定义类型 确保是类
type Constructor = new (...args:any[]) => {}
//  fn必须是个类
function test33(fn:Constructor) {}
@test33
class person33{}

// 给类增加属性和方法  重要!!!
function LogTime<T extends Constructor>(target: T){
    return class extends target{
        createdTime: Date
        constructor(...args: any[]){
            super(...args)
            this.createdTime = new Date()
        }
        getTime(){
            return `该对象的创建时间是${this.createdTime}`
        }
    }
}
@LogTime
class Person4 {
    constructor(public name:string, public sex: string){}
    speack():void{
        console.log(`${this.name}说,我是${this.sex}的`)
    }
} 
interface Person4{
    createdTime: Date,
    getTime():void
}
const person44 = new Person4('程创', '男')
person44.speack()
console.log(person44.createdTime)
console.log(person44.getTime())
// 装饰器增加参数(装饰器工厂)
function LogInfo(n:number){
    return function(target: Function){
        target.prototype.introduct = function () {
            for(let i = 0; i<n; i++){
             console.log('你好。我有一个帽衫');
             
            }
        }

    }
}
interface Person88{
    introduct(): void
}
@LogInfo(5)
class Person88 {
    constructor(public name:string, public age:number){}
    speak(){
        console.log('你好啊!')
    }
}
const person88 = new Person88('程创', 16)
person88.introduct()
// 可以有多个装饰器 @log4j @add
// 属性装饰器 a 对象的原型对象、 b是原型key。如果是静态。则返回类本身。
function Demo1 (target:object, propertyKey:string){
    console.log(target, propertyKey);
    
}
function State(target: object, propertyKey: string){
    let key = `__${propertyKey}`
    Object.defineProperty(target, propertyKey, {
        get(){
            return this.key
        },
        set(newVal){
            console.log(`${propertyKey}的最新值为:${newVal}`)
            this[key] = newVal
        }
    })
}
class Person9{
    @State public name : string
    @Demo1 static school : string
    constructor( name:string, public age: number){
        this.name = name
    }
}
const person99 = new Person9('程创', 18)
person99.name = '22'
//方法装饰器 3个参数。 原型对象、原型key、可操作性(描述)
function FunSpeak(target: object, propertyKey: string, descriptor:PropertyDescriptor){
 console.log(descriptor, 333333);
 // 存储原始方法
 const originnal = descriptor.value
 // 替换原始方法
 descriptor.value = function(...args:any[]){
    console.log(`${propertyKey}开始执行....`);
    const result = originnal.call(this, ...args)
    console.log(`${propertyKey}执行完毕....`);
    return result
 }
 
}
class Person10{
   public name : string
   static school : string
    constructor( name:string, public age: number){
        this.name = name
    }
    @FunSpeak
    speak(){
        console.log(`你好。我得名字是${this.name}, 我得年龄${this.age}`)
    }
}
const person101 = new Person10('张三', 15)
person101.speak()