TypeScript的基本使用(下)

73 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情

4.函数类型

和JavaScript一样,TypeScript函数可以创建有名字的函数和匿名函数。 你可以随意选择适合应用程序的方式,不论是定义一系列API函数还是只使用一次的函数。

1.为函数定义类型

function fn(x: number, y: number): number {
    return x + y;
}

2.可选参数与默认参数

可选参数就是非必须传递的参数,默认参数就是不传这个参数,默认给你带一个固定的参数。

function fn(one: string, two?: string) {
    if(two) {
        return one + "辨认" + two
    }else {
        return one
    }
}
console.log(fn("何必")) // 何必
console.log(fn("何必", "我")) // 何必辨认我

5.返回值类型

function fn(a: number, b: number): number{
    return a+b;
}

fn(1,2);

6.字面量类型

  • 在 TypeScript 中,字面量不仅可以表示值,还可以表示类型,即所谓的字面量类型。
  • 使用值所代表的数据类型来作为变量的数据类型,简单来说,即:值也可以作为类型使用。但要注意,目前只能是string、number和boolean三种数据类型可以写成字面量类型。
const str: "hello typescript" = "hello typescript"
const num: 123 = 123
const bool: true = true

7.泛型

1.什么是泛型

泛型是指在定义函数、接口,或者类的时候,不预先指定具体的类型,而是在使用的时候在指定类型的一种特性。

2.泛型的使用

  • 单类型参数
    一般我们用 T 来代表输入和返回的数据类型,直到调用了才明确 T 是什么数据类型:
function fn<T>(key: number, value: T): Array<T>{
    let arr: T[] = []
    for(var i=0; i<key; i++){
        arr[i] = value
    }
    return arr
}
    
console.log( fn<string>(3, "豪猪") )  

image.png

  • 多个类型参数(方法一)
    如果有多个参数都是类型未知的,那么泛型应该这么写:
// 情况一:多个参数传入
function fn<N, S>(num: N, str: S): Array<N | S>{
    let arr: Array<N | S> = [num, str];
    return arr;
}

console.log(fn(123, "Hello TypeScript")) // [ 123, 'Hello TypeScript' ]

image.png

  • 多个类型参数(方法二)
// 情况二:单个参数传入,且为数组
function fn<N, S>(arr: [N, S]): Array<N | S>{
    let newArr: Array<N | S> = [...arr]
    return newArr
}

console.log(fn([true, 'hello typescript']))  // [ true, 'hello typescript' ]

image.png

8.接口类型

typeScript的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。

1.接口的简单使用

interface IObj {
    name: string,
    age: 18
}

function fn(obj: IObj): void {
    console.log(`我叫${obj.name},今年${obj.age}岁了`);
    
}
fn({name: '小玲', age: 18})

接口的数据是可以打乱的。

2.任意属性

其实属性名称有时也不确定,因此可以使用以下方式定义,但值必须为any。

interface IObj {
    name: string;
    // [propName: string]: string | number;
    // 这个参数名称可能也是不确定的,也不清楚它的类型,可以any,也可指定若干数据类型,建议直接any
    [propName: string]: any; 
}

function fn(obj: IObj): void{
    console.log(`${obj.name}${obj.aa || '水'}货`)
    
}

fn({name: "张三"})				
fn({name: "张三", aa: "坑"})	   
  • 注意属性最好不要和可选属性一起使用,一起使用最好类型一直。

3.可选属性

接口中定义的字段,参数必须传,但有些参数我们希望可传可不传,可以如下:

interface IObj {
    name: string;
    age?: number;	// ?表示该参数可传可不传
}

function fn(obj: IObj): void{
    console.log(`${obj.name}今年${obj.age || 0}岁`)
}

fn({name: "张三"})	// 张三今年0岁

9.类

1.Person类

  • 定义一个Person类
class Person {
    name: string // 声明了Person中name属性必须为string类型
    constructor(name: string){
        this.name = name
    }

    eat(): void{ // 加void表示没有返回值
        console.log(`${this.name}跟🐖一样天天浪费粮食`)
    }
}

let xl = new Person('玲玲')
xl.eat() // 玲玲跟🐖一样天天浪费粮食

2.继承

  • 定义一个Son继承于Person
class Person {
    name: string // 声明了Person中name属性必须为string类型
    constructor(name: string){
        this.name = name
    }

    eat(): void{ // 加void表示没有返回值
        console.log(`${this.name}跟🐖一样天天浪费粮食`)
    }
}

class Son extends Person {
    constructor(name: string) {
        super(name)
    }

    play(): void{
        console.log(`${this.name}又在玩游戏`)
        
    }
}

const tom = new Son("tom")
tom.play() // tom又在玩游戏

3.公共、私有与受保护的修饰符

  • 类属性和方法除了可以通过 extends 被继承之外,还可以通过修饰符控制可访问性。
  • 在 TypeScript 中就支持 3 种访问修饰符,分别是 public、private、protected。

1.公共修饰符public

public 修饰的是在任何地方可见、公有的属性或方法。上述代码中,凡是没有加修饰符的,都是默认已经自带public:

class Person {
    name: string // 声明了Person中name属性必须为string类型
    constructor(name: string){
        this.name = name
    }

    eat(): void{ // 加void表示没有返回值
        console.log(`${this.name}跟🐖一样天天浪费粮食`)
    }
}

const xl = new Person("小玲")
xl.eat()

// 上述代码相当于以下代码:
class Person {
    public name: string
    constructor(name: string){
        this.name = name
    }

    public eat(): void {
        console.log(`${this.name}跟🐖一样天天浪费粮食`)   
    }
}

const xl = new Person("小玲")
xl.eat()

2.私有修饰符private

private 修饰的是仅在当前类中可见、私有的属性或方法。

class Person {
    public name: string // 声明了Person中name属性必须为string类型
    private age: number
    constructor(name: string, age: number){
        this.name = name
        this.age = age
    }

    public eat(): void{ // 加void表示没有返回值
        console.log(`${this.name}跟🐖一样天天浪费粮食,今年${this.age}岁了`)
    }
}

const xl = new Person("小玲", 18) 
xl.eat() // 小玲跟🐖一样天天浪费粮食,今年18岁了
console.log(xl.age) // 属性“age”为私有属性,只能在类“Person”中访问。

image.png

3.受保护修饰符protected

protected 修饰的是仅在类自身及子类中可见、受保护的属性或方法。

class Person {
    public name: string // 声明了Person中name属性必须为string类型
    protected age: number   // 只能在当前类和子类中使用,实例不能使用
    constructor(name: string, age: number){
        this.name = name
        this.age = age
    }

    public eat(): void{ // 加void表示没有返回值
        console.log(`${this.name}跟🐖一样天天浪费粮食,今年${this.age}岁了`)
    }
}

const xl = new Person("小玲", 18) 
xl.eat() // 小玲跟🐖一样天天浪费粮食,今年18岁了
console.log(xl.age) // 属性“age”为私有属性,只能在类“Person”中访问。

class Son extends Person {
    constructor(name: string, age: number){
        super(name, age)
    }
    play(): void {
        console.log(`${this.name}跟🐖一样天天浪费粮食,今年${this.age}岁了`)
    }
}

const yy = new Son('瑶瑶', 18)
yy.play()

4.只读属性与静态属性

a.只读属性readonly

加上readonly的属性只能读不能写:

class Person {
    public readonly name: string
    constructor(name: string){
        this.name = name
    }
}
const yy = new Person("瑶瑶")
yy.name = "小乔" // 无法分配到 "name" ,因为它是只读属性。

b.静态属性static

加上static的属性与方法,无需实例化即可调用:

class Person {
    // 直接给静态属性赋值
    static usename: string = "豪猪"
}

Person.usename // 豪猪

最后

希望这两篇Ts基础使用能给你们带来用处,感谢阅读^-^。