6.typescript:接口+范型

1.接口

在前面我们通过type可以用来声明一个对象类型:

type Point = {
	x: number
	y: number
}

对象的另外一种声明方式就是通过接口来声明

interface Point {
	x: number
	y: number
}

1.1:可选属性

接口中我们也可以定义可选属性

interface Person {
	name: string
	age?: number
	friend?: {
		name:string
	}
}

const person: Person = {
	name:"xiaobai",
	age: 18,
	friend: {
		name:"kobe"
	}
}

console.log(person.name)
console.log(person.friend?.name)

1.2:只读属性

意味着我们再初始化之后,这个值是不可以被修改的

interface Person {
	readonly name: string
	age?: number
	readonly friend?: {
		name:string
	}
}

const person: Person = {
	name:"xiaobai",
	age: 18,
	friend: {
		name:"kobe"
	}
}
person.name = "xxx" //不可以设置
person.friend = {}//不可以设置
//下面的代码可以执行
if(person.friend){
	person.friend.name = "123"
}

1.3:索引类型

interface FrontLanguage {
	[index: number]: string
}

const frontend: FrontLanguage = {
	1:"HTML",	
	2:"CSS",
	3:"JavaScript"
}

1.4:函数类型(但是一般建议使用type)

前面我们都是通过interface来定义对象中普通的属性和方法的,实际上它也可以用来定义函数类型

interface CalcFunc {
	(num1: number,num2: number): number
}
const add: CalcFunc = (num1,num2) => {
	return num1 + num2
}

1.5:接口继承(多继承)

使用extends关键字
接口是支持多继承的(类不支持多继承)

interface Person {
	name: string
	eating: () => void
}

interface Animal {
	running: () => void
}
interface Student extends Person,Animal {
	sno: number
}

const stu: Student = {
	sno: 110,
	name: "xiaobai",
	eating: function() {},
	running: function() {},
}

1.6:接口对于类的实现

接口定义后,也是可以被类实现的:
如果被一个类实现,那么在之后需要传入接口的地方,都可以将这个类传入;
这就是面向接口开发;

interface ISwim {
	swimming: () => void
}
interface IRun {
	running: () => void
}
class Person implements ISwim,IRun {
	swimming() {
		console.log("swimming")
	}
	running() {
		console.log("running")
	}
}

function swim(swimmer:ISwim) {
	swimmer.swimming()
}

const p = new Person()
swim(p)

1.7:交叉类型

在开发中,我们进行交叉时,通常是对对象类型进行交叉的

interface Colorful {
	color: string
}
interface IRun {
	running: () => void
}

type NewType = Colorful & IRun

const obj: NewType = {
	color: "red",
	running:function(){}
}
  • interface和type区别
    1.interface和type都可以用来定义对象类型
    2.如果是定义非对象类型,通常推荐使用type
    3.如果是定义对象类型,那么他们是有区别的:
    i: pinterface 可以重复的对某个接口来定义属性和方法;
    ii: p而type定义的是别名,别名是不能重复的

1.8:字面量赋值

interface IPerson {
	name: string
	eating: () => void
}
const p: IPerson = {
	name: "xiaobai",
	age: 18,
	eating: function(){}
}
//会报错
interface IPerson {
	name: string
	eating: () => void
}
const p = {
	name: "xiaobai",
	age: 18,
	eating: function(){}
}
const p: IPerson = obj

这样就不会了
这是因为TypeScript在字面量直接赋值的过程中,为了进行类型推导会进行严格的类型限制。
但是之后如果我们是将一个 变量标识符 赋值给其他的变量时,会进行freshness擦除操作。

2.范型

泛型实现类型参数化

function foo(arg: any): any {
	return arg
}
foo("abc")
foo(123)

以下是范型

function foo<Type>(arg: Type): Type {
	return arg
}
foo<string>("abc")
foo<number>(123)

当然我们也可以传入多个类型:

function foo<T,E>(a1: T, a2: E){}

平时在开发中我们可能会看到一些常用的名称:

  • T : Type:类型
  • K、V:key和value,键值对
  • E:Element元素
  • O:Object对象
interface IFoo<T> {
	initialValue: T,
	valueList: T[],
	handleValue: (value: T) => void
}
const foo: IFoo<number> = {
	initialValue: 0,
	valueList: [0,1,3],
	handleValue: function(value: number) {
		console.log(value)
	}
}

2.1:泛型类

class Point<T> {
	x: T
	y: T
	
	constructor(x: T,y: T) {
		this.x = x
		this.y = y
	}
}

const p1 = new Point(10,20)
const p2 = new Point<number>(10,20)
const p3: Point<number> = new Point(10,20)

2.2:泛型约束

有时候我们希望传入的类型有某些共性,但是这些共性可能不是在同一种类型中:
比如string和array都是有length的,或者某些对象也是会有length属性的;
那么只要是拥有length的属性都可以作为我们的参数类型,那么应该如何操作呢?

interface ILength {
	length: number
}

function getLength<T extends ILength>(args: T) {
	return args.length
}
console.log(getLength("abc"))
console.log(getLength(["abc","cba"]))
console.log(getLength({length:100,name:"xiaobai"}))
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值