TypeScript

本文详细介绍了TypeScript的核心特性,包括它的类型系统如何增强JavaScript的健壮性,如何实现类的继承以及抽象类的概念。此外,还探讨了接口的使用,类型别名(type)与接口(interface)的区别,并介绍了泛型在提高代码复用性和灵活性方面的作用。通过对这些概念的深入理解,开发者可以更好地掌握TypeScript并应用于大型项目。
摘要由CSDN通过智能技术生成

Typed JavaScript at Any Scale.
添加了类型系统的 JavaScript,适用于任何规模的项目。

以上描述是官网对于 TypeScript 的定义。

它强调了 TypeScript 的两个最重要的特性——类型系统、适用于任何规模。


什么是TypeScript?

        TypeScript就是所谓的JavaScript超集。它不是JavaScript的替代品,也不会为JavaScript代码添加任何新功能。相反,TypeScript允许程序员在其代码中使用面向对象的构造,然后将其转换为JavaScript。 


ts中的继承

class Person{
    name!:string;
    age:number;

    constructor(name:string, age:number) {
        this.name = name;
        this.age = age;
    }
    running(){
        console.log(this.name + " running")
    }
    eating(){
        console.log(this.name + " eating")
    }
}
class A{}
//Classes can only extend a single class.
// class Student extends Person, A{
class Student extends Person{
    learn: string;
    constructor(name:string, age:number, learn: string) {
        super(name, age);
        this.learn = learn
    }
    running(){
        //this ==> s
        //super===> Person
        super.running()
        console.log(this.name + " Student running")
    }
}

let s: Student = new Student("学生", 20, "TypeScript");
s.running();
s.eating();
console.log(s)

ts中的成员修饰符

//在typeScript中 类的属性和方法支持三种修饰符
//1 public
//  修饰的是在任何地方可见 公有的属性或方法 默认编写的属性就是public的
//2 private
//  修饰的是仅在同一类中可见 私有的属性或方法(不参与继承)
//3 protected
//  修饰的是仅在类自身及子类中可见 受保护的属性或方法(不能读写)
//4 readonly
//  修饰的是这个属性我们不希望外界可以任意的修改,只希望确定值之后直接使用(只能读)


class Person{
    public name!:string;
    public age:number;

    constructor(name:string, age:number) {
        this.name = name;
        this.age = age;
    }
    running(){
        console.log(this.name + " running")
    }
    eating(){
        console.log(this.name + " eating")
    }
}
class Student extends Person{
    public learn: string;
    constructor(name:string, age:number, learn: string) {
        super(name, age);
        this.learn = learn
    }
    running(){
        //this ==> s
        //super===> Person
        super.running()
        console.log(this.name + " Student running")
    }
}

let s: Student = new Student("学生", 20, "TypeScript");
s.running();
s.eating();
console.log(s)


//private 修饰
class Person{
    private name:string;
    constructor(name:string) {
        this.name = name;
    }
}

let p = new Person("aa");
console.log("=======>",p)


//protected 修饰
class Person{
    protected name:string;
    constructor(name:string) {
        this.name = name;
    }
}

let p = new Person("aa");


//readonly 修饰
class Person{
    readonly name:string;
    constructor(name:string) {
        this.name = name;
    }
}

let p = new Person("aa");


ts中的抽象类

//多态 => 编译多态 运行多态
//编译多态=>指为不同数据类型的实体提供统一的接口(把相关的数据整合起来通过同一个接口去调用)
//运行多态=>重载和重写

//继承是多态(编译多态)使用的前提
//在定义很多通用的接口时,通常会让调用者传入父类, 通过多态来实现更加灵活的调用方式
//但是,父类本身其实并不需要对某些方法进行具体的实现,所以父类中定义的方法,可以定义为抽象方法

//抽象方法=>
//在ts中没有具体实现的方法(抽象方法)
//抽象方法, 必须存在于抽象类中
//抽象类必须使用 abstract声明

//抽象类=>
//抽象类是不能被实例化的(也就是不能通过new关键字来创建);
//抽象方法必须被子类实现, 否则该类必须是一个抽象类


//抽象类 abstract
abstract class Shape{//形状类
    //抽象方法
    abstract getArea():number
}
class Rectangle extends Shape{//矩形类
    public width: number
    public height: number
    constructor(width: number, height: number) {
        super()
        this.width = width
        this.height = height
    }
    getArea(){
        return this.width * this.height
    }
}
let rectangle = new Rectangle(100,100);
class Circle extends Shape{//圆形类
    public r: number
    constructor(r: number) {
        super()
        this.r = r
    }
    getArea(){
        return this.r * this.r * 3.14
    }
}
let circle = new Circle(100);


function getArea(shape:Shape){//获取面积
    console.log(shape.getArea())
}

getArea(rectangle)// width height
getArea(circle)// R

//抽象类 不能使用new创建 不能被实例化
// let shape = new Shape()
// getArea(shape)//shape => {getArea(){}}


 ts中的接口:interface 

 定义接口允许您检查变量组合以确保它们使用一致。接口不会转换为JavaScript; 他们唯一的目的是帮助开发者。例如,您可以使用以下属性和类型定义接口:

interface Food {
    name: string;
    calories: number;
}

 interface的继承

interface Obj {
    name: string,
    run: () => void
}

interface Obj2 {
    age: number
}

//接口是支持多继承的(类的继承只能继承一个)
interface Obj12 extends Obj, Obj2 {
    jump: () => void
}
let obj: Obj12 = {
    name: "你好",
    age: 18,
    run(){},
    jump(){}
}

interface和type的区别

//我们发现interface和type都可以用来定义类型, 那么在开发过程中,到底应该选择哪个
//1. 如果定义的是对象类型,那么通常推荐使用interface
//2. 如果定义的是非对象 function Direction 推荐使用type

//interface和type之间有什么异同
//1.interface可以重复声明  type不能重复声明
//2.type定义的别名, 别名是不能重复

/*type Person = {
    name: string,
    run:()=>void
}
type Person = {
    age: number
}*/

interface Person {
    name: string,
    run:()=>void
}
interface Person {
    age: number
}

let obj: Person = {
    name: "aa",
    run(){},
    age: 18
}

/*let img = document.getElementById("img") as HTMLImageElement
let div = document.getElementById("div") as HTMLDivElement

window.navigator.userAgent //==>当前浏览器信息
interface Window{
    helloWorld: string
}
window.helloWorld = "你好世界"*/

ts中的泛型

//在开发过程中 一些时候我们声明的函数不仅仅要明确他的数据类型,而且还要考虑这个方法具有很强的可复用性
//实现类型参数化  ==>泛型
//定义一个方法,在方法中不去确定参数到底是什么类型,而是需要使用者来进行传递


interface IObj{
    name: string,
    age: number
}
//不确定用户传递什么类型的参数回来 那么也就不能确定返回值

//类型的参数化

//在定义这个函数的时候, 我们不去决定这些参数的类型
//而是让调用者以参数的形式告诉我们函数的参数应该是什么类型

//泛型函数
//函数中在函数名的后面通过<形参>的形式,接受传递过来的类型
function fn<T=string>(arg:T):T{
     console.log(arg)
    return arg
}


//泛型函数调用
//1通过<类型> 的方式将类型传递给函数
fn<string>("1234")
//2通过类型推导,自动的推导出我们传入变量的类型
//  在这里会推导出他们是字面量类型, 当然字面量类型对我们的函数也是适用的
fn<number>(123)
//引用类型会推导出想要的效果
fn<number[]>([1,2,3])
fn({a:1})
fn([1,2,3])


//通过泛型的形式来确定变量的数据类型
let arr: string[] = ["1","2","3"]
let arr1: Array<string> = ["1","2","3"]
let arr2: Array<number> = [1,2,3,4]

//泛型=>  泛指所有类型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值