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扩展
不同点:
- type 可以声明类型别名,联合类型,元组
- typeof获取类型可以赋值到type
type t = typeof something
- 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')