typescript笔记2 函数 类 接口

函数

方法传参

let func = function(name:string, age:number):string{
	return `${name}:${age}`
}
// 对象类型,对象属性可以用逗号或者分号分隔
let func1 = function(p:{ name:string, age:number }):string{
	return `${p.name}:${p.age}`
}

注: 参数解构时冒号语法含义为别名而非类型声明

type Person = {name:string,age:number}
let func1 = function({ name:_name, age:_age } : Person):string{
	return `${_name}:${_age}`
}

可选参数

es5中方法实参和形参可以不一样,但是ts中必须一样,如需不一样可配置为可选参数
注:可选参数必须配置在最后面

function func(name:string, age?:number):string{}
function func(p:{ name:string, age?:number}):string{}

默认参数

es6, ts中可指定参数默认值,配置了默认值的参数也是可选参数

function func(name:string, age:number = 20):string{}

剩余参数

使用扩展运算符(…)传递多个参数

function func(...nums:number[]):number{
	for(let i=0;i<nums.length;i++){}
	return 0
}

泛型参数

function func<Type>(arr: Type[]): Type | undefined { 
    return arr[0]
}
func<string | number>(['a','b', 1, 4]) // 可调用时指定类型
func([1,2,3]) //可根据参数类型自动推断返回类型

泛型参数约束

function func<Type extends { length: number }>(a: Type, b: Type): Type { 
	if(a.length >= b.length) {
		return a;
	} else {
		return b;
	}
}
func<string>('abc','cdefg')
func([1,2,3],[4,5]) 

函数重载

实现函数必须兼容所有重载签名
调用时也必须与重载签名匹配

function func(name:string):string; // 重载签名
function func(name:string,age?:number):string; // 重载签名
function func(name:string,age?:number):string { // 实现签名
    return ''
}
func1('PSR')
func1('PSR',18)
func1(true) // 报错

注:能使用联合类型参数,就不使用重载参数

function len1(x: any[] | string){
	return x.length
}
function len2(s:string):number
function len2(arr:any[]):number
function len2(x:any){
	return x.length
}
len1(Math.random()>0.5?'hello':[4,5,6]
len2(Math.random()>0.5?'hello':[4,5,6] // 报错,因为此处参数为联合类型 string | any[] 与重载签名参数不兼容

函数类型表达式

function call(fn: (name:string) => string){
	fn('hello')
}
type Func = (name:string) = > string
function call1(fn: Func){}

调用函数签名

type Func = {
	description: string
	(name: string): string
}
function call(fn: Func){
	console.log(`${fn.description} returnd: ${fn('hello')}`)
}
function func1(name:string):string {
	return string
}
func1.description = 'func1'

构造函数签名

type MyConstructor = {
	new (s: string): MyClass
}
function fn(c: MyConstructor) {
	return new c('hello')
}

同时使用两种签名

type CallOrConstructor {
	new (s: string): Date
	(n: number): number
}
function fn(date: CallOrConstructor) {
	let d = new date('2022')
	let n = date(2022)
}

es5

function Person(name) {
    this.name = name // 实例属性
    this.func1 = function () {
        // 实例方法
    }
}
Person.prototype.age = 18 // 静态属性
Person.prototype.func2 = function () {
    // 静态方法
}
// 对象冒充继承,继承实例属性和方法,无法继承静态属性和方法,实例化子类时可以给父类传参
function Student(name) {
    Person.call(this, name)
}
// 原型链实现继承,可以继承所有属性方法,实例化子类时无法给父类传参
Student.prototype = new Person()

ts

class Person {
    name: string; // 实例属性
    constructor(name: string) { // 构造函数
        this.name = name
    }
    setName(name: string): void {
        // 实例方法
        this.name = name
    }
    getName(): string {
        return this.name
    }	
	static func1(): void {
		// 静态方法
	}
}

let p = new Person('张三')

// 继承
class Student extends Person {
    constructor(name: string) {
        super(name);
    }
    setName(name: string) { // 重写函数
        super.setName(name);
        console.log(name)
    }
}

访问修饰符

public,private protected

class Person{
	name: string; // 默认公有
	private age: number;
	protected setName(name:string): void {
	}
}

抽象

抽象类不能直接被实例化,抽象方法只能在抽象类中定义

abstract class Person {
	abstract eat():void;
}
class Student extends Person {
	eat():void {
	}
}

泛型类

class MyClass<T> {
	list:T[]=[]
	add(value:T):void{
		this.list.push(value)
	}
	get(index:number):T {
		return this.list[number]
	}
}

接口

对象接口

interface FullName {
    firstName: string
    lastName: string
}
function func(name: FullName): void {
    console.log(`${name.firstName} - ${name.lastName}`)
}
let obj = {
    age: 20,
    firstName: 'p',
    lastName: 'r'
}
func(obj) // 不报错
func({
    firstName: 'p',
    lastName: 'r',
    age: 20 // 报错
})

扩展接口

interface FullName {
    firstName: string
    lastName: string
}
// 扩展并定义新接口
interface FullName2 extends FullName {
	middleName: string
}
// 声明合并,直接给接口增加属性
interface FullName {
	nickName: string
}

交叉类型

类型不可以修改,声明后不可增加属性

type FullName = {
	firstName: string
	lastName: string
}
// 扩展并定义新类型
type FullName2 = FullName & {
	middleName: string
}

函数接口

约束参数和返回值,可对this指针进行指派

interface func {
	(key:string, value:string):string
}
let func1:func = function(key:string,value:string):string{
	return ''
}

类接口

对类的约束 和抽象类类似

interface Animal {
	name:string
	eat(str:string):void
}
class Dog implements Animal {
	name:string
	constructor(name:string){}
	eat() { // 可以不写参数,但是不实现此函数会报错
		console.log(this.name)
	}
}

与type异同

相同点:都能定义对象类型和接口类型,都可以通过extends扩展
不同点:

  1. type 可以声明类型别名,联合类型,元组
  2. typeof获取类型可以赋值到type
type t = typeof something
  1. interface可以声明合并

泛型接口

在函数调用时传递泛型参数

interface ConfigFn{
	<T>(value:T):T;
}
let getData:ConfigFn = function<T>(value:T):T{
	return value;
}
getData<string>('1234')

在接口实现时传递泛型参数

interface ConfigFn<T>{
	(value:T):T;
}
let getData:ConfigFn<string> = function(value:string):string{
	return value;
}
getData('1234')

posted on 2022-04-11 22:37  路过君  阅读(41)  评论(0编辑  收藏  举报

导航