关于javascript:TypeScript四-函数接口类泛型语法总结

10次阅读

共计 5872 个字符,预计需要花费 15 分钟才能阅读完成。

目录

  • 函数类型

    • 函数申明
    • 函数类型表达式
    • 可选参数
    • 任意个数的参数
  • 接口(interface)

    • 定义接口
    • 应用接口
    • 选成员 & 只读成员 & 动静成员
    • 须要对类的属性与办法进行申明
    • 类成员拜访修饰符(public/private/protected)

        1. 定义一个构造函数
        1. 初始化实例对象并拜访构造函数成员
        1. 创立子类继承构造函数并拜访其成员
    • 类的构造函数被私有化
    • 类的只读属性
    • 类与接口

      • 定义接口
      • 实现接口
    • 抽象类

      • 抽象类定义
      • 子类继承
  • 泛型

    • 定义泛型参数
    • 调用时传入泛型参数的类型
  • TypeScript 学习地图

函数类型

函数的输出和输入进行束缚,及参数和返回值

函数申明

// 参数的类型和返回值的类型
function func1(a: number, b: number): string {return 'func1'}
// 参数类型和个数是固定的,否则报错
func1(100, 200)

函数类型表达式

// 一般函数
const func4 = function (a: number, b: number): string {return 'func2'}
// 应用箭头函数
const func5: (a: number, b:number) => string = function(a, b) {return 'func2'}

可选参数

可选参数肯定要在必选参数前面,放在函数最初。

// 能够在 b 前面增加问号示意可选,也能够间接设置默认值,也能够不必传
function func2(a: number, b: number = 10, c?: number): string {return 'func1'}

func1(100)

任意个数的参数

应用 ES6rest操作符

function func3(a: number, b: number = 10, ...rest: number[]): string {return 'func1'}

func1(100,200,300,400)

接口(interface)

接口,是一种标准、契约,约定对象的构造。

接口是用来束缚一个对象的构造,咱们要应用这个接口,就要遵循其全副的约定。

接口最直观的体现就是 对象应该有哪些成员以及成员的类型都是什么样的?

定义接口

// 定义一个接口,外面确定要有两个成员,且都是字符串类型
interface Post {
  title: string  // 结尾能够应用逗号分隔,也能够应用分号去宰割,还能够省略
  content: string
}

应用接口

// 应用的时候申明参数是 Post 类型,外面应用的时候不放心没有值
function printPost (post: Post) {console.log(post.title)
  console.log(post.content)
}

// title 和 content 任何一个没有传或者不是字符串都会报错
printPost({
  title: 'this is a title',
  content:'this is a content'
})

可选成员 & 只读成员 & 动静成员

  • 可选成员 : 定义接口的时候增加问号,传参的时候可有可无
interface Post {
  title: string
  content: string
  subtitle?: string // 可选成员, 可有可无,string or undefined
}

// 上面不传 subtitle 不会报错
const hello: Post = {
    title: 'this is a title',
    content:'this is a content'
}
  • 只读成员 :定义接口的时候后面增加readonly 关键词,一经定义不能批改
interface Post {
  title: string
  content: string
  subtitle?: string
  readonly summary: string // 只读成员,一经定义不能更改
}

const hello: Post = {
    title: 'this is a title',
    content:'this is a content',
    summary: 'this is a summary'
}

hello.summary = 'hello' // 报错
  • 动静成员:不确定有哪些成员,本人定义增加,个别这种都存在动静对象外面,例如程序中的缓存对象。

因为不晓得有哪些成员名称,所以 Cache 外面应用 [],指定键prop 的类型是string,值的类型是number

interface Cache {[prop: string] : number
}

const cache: Cache = {}

cache['hello'] = 1
cache['hi'] = 2

类用来形容一类具体事物的形象特色。TypeScript加强了 class 的相干语法,拜访修饰符以及抽象类的概念等 …

上面看一下 TypeScript 新增的内容:

须要对类的属性与办法进行申明

目标是为了给属性和办法做类型标注

class Person {
  // 须要对类的属性进行申明,能够增加默认值,也能够不增加
  // 两者有一个没有写,都会报错
  name: string = 'init name'
  age: number
  
  constructor (name: string, age: number) {
    // 如果不加申明,这里间接应用会报错,因为在 TypeScipt 须要明确属性,而不是动静增加
    this.name = name
    this.age = age
  }
  
  // 办法这些和之前是一样的,也要增加类型注解
  sayHi (msg: string): void {console.log(`I am ${this.name}, ${msg}`)
  }

  run (): void {this.sayHi('I am happy!')
  }
}

类成员拜访修饰符(public/private/protected)

public private protected
外部拜访
内部拜访 不可 不可
子类拜访 不可
1. 定义一个构造函数
class Person {
  // 默认是 public,加不加成果一样,倡议去加
  public name: string = 'init name'
  // age 属性是个公有属性,公有属性能够在函数外部通过 this.age 去拜访
  private age: number
  // 受爱护的,外界成员不可拜访,子类成员能够拜访
  protected gender: boolean

  constructor (name: string, age: number) {
    this.name = name
    this.age = age
    this.gender = true
  }

  sayHi (msg: string): void {console.log(`I am ${this.name}, ${msg}`)
    console.log(this.age) // 本人外部拜访公有属性是没有问题的
    console.log(this.gender) // 本人外部拜访受爱护属性是没有问题的
  }
}
2. 初始化实例对象并拜访构造函数成员
const xm = new Person('xm', 18)
console.log(xm.name)
console.log(xm.age) // 报错,Property 'age' is private and only accessible within class 'Person'
console.log(xm.gender) // 报错,Property 'gender' is protected and only accessible within class 'Person' and its subclasses.
3. 创立子类继承构造函数并拜访其成员
// 定义一个 Student 类继承 Person
class Student extends Person {constructor(name: string, age: number) {super(name, age)
    console.log(this.gender)
    console.log(this.age) // 报错,公有成员不能拜访
    console.log(this.name)
  }
}

类的构造函数被私有化

  • private:如果类的构造函数被私有化,那么不能被实例化和继承,这个时候只能在这个类的外部增加一个静态方法,通过静态方法增加实例。
  • protected:如果类的构造函数被受爱护,那么不能实例化,然而能够继承。
class Student extends Person {private constructor(name: string, age: number) {super(name, age)
    console.log(this.gender)
    console.log(this.name)
  }
  // 能够定义一个办法外部实例化
  static create (name: string, age: number) {return new Student(name, age)
  }
}

const xm = Student.create('xm', 18)
console.log(xm.name)

类的只读属性

在属性前增加修饰符readonly,如果有拜访修饰符,那么就跟在修饰符的前面. 只读属性必须在申明时或构造函数里被初始化。

class Person {
  public name: string = 'init name'
  private age: number
  // 如果有拜访修饰符,那么就跟在修饰符的前面
  protected readonly gender: boolean

  constructor (name: string, age: number) {
    this.name = name
    this.age = age
    this.gender = true
  }

  sayHi (msg: string): void {console.log(`I am ${this.name}, ${msg}`)
    console.log(this.gender = false) // Cannot assign to 'gender' because it is a read-only property.
  }

  run (): void {this.sayHi('I am happy!')
  }
}

let xm = new Person('xm', 18)
xm.gender = 'false' // 报错

类与接口

类与类之间的公共特色个别会用接口去形象

比方上面两个不同的类,然而都有 eatrun两个雷同的办法,能够用接口束缚两个类中公共的局部

class Person {eat (food: string): void {console.log(` 优雅进餐:${food}`)
  }

  run (distance: number) {console.log(` 直立行走:${distance}`)
  }
}

class Animal {eat (food: string): void {console.log(` 不优雅进餐:${food}`)
  }

  run(distance: number) {console.log(` 匍匐:${distance}`)
  }
}
定义接口
// 能够定义一个接口实现一个能力,而后让一个类实现多个接口

interface Eat {eat (food: string): void
}

interface Run {run (distance: number): void
}
实现接口
// Person 和 Animal 要实现接口,如果外面少了接口对应的办法, 就会报错。class Person implements Eat, Run{eat (food: string): void {console.log(` 优雅进餐:${food}`)
  }

  run (distance: number) {console.log(` 直立行走:${distance}`)
  }
}

class Animal implements Eat, Run{eat (food: string): void {console.log(` 不优雅进餐:${food}`)
  }

  run(distance: number) {console.log(` 匍匐:${distance}`)
  }
}

抽象类

  • 抽象类与接口有些相似,也是束缚子类中必须要有哪些成员,不同的是抽象类外面能够蕴含一些具体的实现
  • 抽象类只能继承,不能实例化对象
  • 抽象类中能够定义一些形象办法
  • 形象办法不须要办法体,当父类中有形象办法的时候,子类必须要实现形象办法
抽象类定义
// 增加 abstract 关键词之后就成为了抽象类
abstract class Animal {eat (food: string): void {console.log(` 不优雅进餐:${food}`)
  }
  // 抽象类中能够定义一些形象办法,也须要关键词 abstract
  abstract run (distance: number): void
}
子类继承
class Dog extends Animal {
  // 能够在 VSCode 环境点击 Dog 应用疾速修复主动生成代码实现
  // 这里实现了抽象类中的 run 形象办法
  run(distance: number): void {console.log('匍匐', distance)
  }
}

// 子类实例化
const d = new Dog()
d.eat('食粮')
d.run(100)

泛型

咱们在定义函数、接口或者类的时候没有去指定类型,只有当应用的时候才去指定类型的一种特色。

其目标 就是为了极大水平复用咱们的代码

举个例子:

上面是传入长度和值,返回一个数组

// 参数长度是 number 类型,value 是 number 类型,返回的是 number 类型的数组
function createArray (length: number, value: number): number[] {const arr = Array<number>(length).fill(value)
  return arr
}

// 上面传入参数能够取得三个值为 100 的数字类型的数组
const res = createArray(3, 100) // res => [100, 100, 100]

下面的代码有个缺点是只能返回数字类型的数组,如果换成其余类型就会报错,如何进行批改?

定义泛型参数

  • 函数名前面应用尖括号,外面定义泛型参数
  • 个别泛型参数都用大写的 T 作为名称,函数中不明确的类型都用 T 去代表
function createArray <T> (length: number, value: T): T[] {const arr = Array<T>(length).fill(value)
  return arr
}

调用时传入泛型参数的类型

  • 调用时在函数名前面用尖括号外部填入参数的类型
// 上面能够填充字符串类型或者数字类型都能够
const res = createArray<string>(3, 'foo')
const res1 = createArray<number>(3, 100)

总结 就是泛型参数将定义时不能明确的参数用一个T 来代替,应用的时候指定 T 的类型

TypeScript 学习地图

正文完
 0