typescript 接口

/**
 类型检查器会查看printLabel的调用。
 printLabel有一个参数,并要求这个对象参数有一个名为label类型为string的属性。
 需要注意的是,我们传入的对象参数实际上会包含很多属性,但是编译器只会检查那些必需的属性是否存在,并且其类型是否匹配
 */

// function printLabel(labelledObj: { label: string }) {
//     console.log(labelledObj.label)
// }
//
// let myObj = {size: 10, label: '这个属性必须是个字符串类型'}
// printLabel(myObj)

/**
 * 使用接口描述
 */

// interface LabelValue {
//     label: string
// }
//
// function printLabel(labelledObj: LabelValue) {
//     console.log(labelledObj.label)
// }
//
// let myObj = {size: 10, label: '使用接口来描述'}
// printLabel(myObj)

/**
 * LabelledValue接口就好比一个名字,用来描述上面例子里的要求。
 * 它代表了有一个 label属性且类型为string的对象。
 * 需要注意的是,我们在这里并不能像在其它语言里一样,说传给 printLabel的对象实现了这个接口。我们只会去关注值的外形。
 * 只要传入的对象满足上面提到的必要条件,那么它就是被允许的。
 *  还有一点值得提的是,类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。
 */


/**
 * 可选属性
 接口里的属性不全都是必需的。 有些是只在某些条件下存在,或者根本不存在。
 */

interface SquareConfig {
    color?: string,
    width?: number
}

/**
 * 带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个 ? 符号。
 */
function createSquare(config: SquareConfig): { color: string, area: number } {
    let newSquare = {color: 'blue', area: 100}
    if (config.color) {
        newSquare.color = config.color
    }
    if (config.width) {
        newSquare.area = config.width * config.width
    }
    return newSquare
}

let mySquare = createSquare({color: 'pink'})
console.log(mySquare)


/**
 * 只读属性
 一些对象属性只能在对象刚刚创建的时候修改其值。 你可以在属性名前用 readonly来指定只读属性:
 */

interface Point {
    readonly x: number,
    readonly y: number
}

let p1: Point = {x: 10, y: 5}
// p1.x = 5  //Cannot assign to 'x' because it is a read-only property.
console.log(p1)

/**
 * ReadonlyArray<T> 它与Array<T>相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改:
 */
let a: number[] = [1, 2, 3]
let ro: ReadonlyArray<number> = a
// ro[0] = 5 //err
/** ro 的内容不能再更改了 就算把整个ReadonlyArray赋值到一个普通数组也是不可以的*/
/** 但是可以使用类型断言 */
a = ro as number[]
console.log(ro, a)

/** readonly vs const
 最简单判断该用readonly还是const的方法是看要把它做为变量使用还是做为一个属性。 做为变量使用的话用 const,若做为属性则使用readonly。*/


/**
 * 函数类型
 * 为了使用接口表示函数类型,我们需要给接口定义一个调用签名。 它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。
 */
interface InterFn {
    (age: number, fullName: string): string
}

let myFn: InterFn
/** 函数的参数名不需要与接口里定义的名字相匹配  但要求对应位置上的参数类型是兼容的 因为函数直接赋值给了 SearchFunc类型变量*/
/** 可以不指定类型 但是对应位置不能指定错误的类型 */
// myFn = (age: number, fullName: string) => {
myFn = (age, fullName) => {
    let explain = `年龄:${age}     姓名:${fullName}`
    return explain
}
let user_str = myFn(23, 'LWT')
console.log(user_str)


/**
 * 可索引的类型
 * 可索引类型具有一个 索引签名,它描述了对象索引的类型,还有相应的索引返回值类型。
 * TypeScript支持两种索引签名:字符串和数字。 可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。
 */
interface StrArr {
    [index: number]: string
}

let arrIndex: StrArr = ['LWT', 'WLP']
let myName: string = arrIndex[0]
console.log(myName)


/**
 * 继承接口
 */
interface Shape {
    color: string
}

interface Super extends Shape {
    age: number
}

let star = <Super>{}
star.color = 'red'
star.age = 20
console.log(star.color)
console.log(star.age)

/** 一个接口可以继承多个接口,创建出多个接口的合成接口。 */
interface Car {
    name: string
    width: number
    height: number
}

interface Price {
    price: number
}

interface Introduce extends Car, Price {

}

let car = <Introduce>{}
car.name = '汽车'
car.width = 1500
car.height = 300
car.price = 20000
console.log(car)

// car.color = 'red' 报错 Property 'color' does not exist on type 'Introduce'.


/**
 * 混合类型
 * 一个对象可以同时做为函数和对象使用,并带有额外的属性。
 */
interface ToDay {
    weather: string

    (mood: string): string

    funny(): void
}

function initToDay(): ToDay {
    let day = <ToDay>function (wearther: string) { }
    day.weather = 'sunny day'
    day.funny = function () { }
    return day
}
let day = initToDay()
console.log(day.weather)
day('sunny day')
day.funny()

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值