【TS】Interface接口

本文深入探讨了TypeScript中的接口(Interface)概念,包括其用于描述对象形状、抽象类的抽象以及实现鸭子类型的机制。通过示例展示了如何定义接口,如IPerson,以及如何在类(如User)中实现接口。同时,接口还可用于定义函数类型,如Sayhi。此外,接口支持继承,如Teacher接口扩展了Person接口。最后,接口与type的区别在于type只能定义基本类型,而接口能定义更复杂的结构。

Interface定义

在TypeScript里,接口的作用就是定义Object类型,非常灵活有以下功能:

  1. 对对象(object)的形状(shape)进行描述。如属性、方法;
  2. 对类(class)进行抽象。在面向对象语言中较为常见;
  3. Duck Typing(鸭子类型)。如果某东西具有鸭子的特性,就可以将它看作鸭子,是动态编程语言中对象的一种推断策略,更关注对象如何被使用,而不是对象的类型本身。
interface IPerson {
    readonly id: number; //readonly 只读属性
    name: string;
    age?: number; // ?标识符表示是可选属性
    [propName: string]: any; //预留属性
    say(): string; // 返回值类型
}

let viking: IPerson = {
    id: 1,
    name: 'viking',
    age: 20,
    say() {
        return 'say hello'
    }
}
viking.id = 2 // 试图改写只读属性id将为语法报错

class 应用 interface

类应用接口,一个类应用接口之后,必须具备接口里应有的属性和方法。

class User implements Person {

    name: 'lily',
    say() {
        return 'hello'
    }

}

interface 的继承

interface Person {
    name: string;
    age?: number;
    [propName: string]: any;
    say(): string;
    teach(): string;
}
interface Teacher extends Person {
    teach(): string
}

let viking: Teacher = {
    name: 'lily',
    say(){
        return 'hello'
    },
    teach() {
        return 'tech'
    }
}

用interface定义函数类型

interface Sayhi {
    (word: string): string. // (参数:类型):返回值类型
}

const say: Sayhi = (word: string) => {
    return word
}

interface 和 type(类型别名) 

type可以直接定义基础类型,interface必须定义对象或方法。

interface可以定义属性、方法、使用propName预留属性,可以使用 readonly 和 ? 标识只读和非必填。另外,Interface可继承,可以定义具体的方法类型,

<think>我们被要求提供TypeScript接口(interface)的使用方法和特性。根据用户提供的引用内容,我们可以总结如下: 1. 引用[1]展示了接口的基本用法:使用interface关键字定义对象类型,然后用于函数参数的类型标注。 2. 引用[2]提到接口可以将内联类型抽离出来实现复用,同时提到类型别名(type)也可以实现类似功能,但接口和类型别名有一些区别(尽管这里没有深入)。 3. 引用[3]展示了接口的更多特性:可选属性、只读属性以及索引签名。 4. 引用[4]提到了一个构造器签名的例子(使用new关键字),这通常用于描述类的构造函数类型,但用户表示有疑问。 因此,我们可以组织以下内容: ### TypeScript接口(interface)的使用和特性 接口interface)是TypeScript中用于定义对象类型的一种强大方式,它主要用来描述对象的形状(shape),即对象应该具有哪些属性以及属性的类型。接口的主要目的是类型检查,确保数据满足特定的结构。 #### 1. 基本用法 使用`interface`关键字定义接口,然后可以将该接口用作类型注解。 例如: ```typescript interface User { name: string; age: number; } function printUser(userObj: User) { console.log(userObj.name); } const myObj = { name: 'lio', age: 18 }; printUser(myObj); // 正确 ``` #### 2. 可选属性 如果某些属性不是必须的,可以使用`?`标记为可选属性。 ```typescript interface Person { name: string; age?: number; // 可选 } const p1: Person = { name: "Alice" }; // 正确,age可选 ``` #### 3. 只读属性 使用`readonly`关键字可以将属性设置为只读,初始化后不可修改。 ```typescript interface Point { readonly x: number; readonly y: number; } let p: Point = { x: 10, y: 20 }; p.x = 5; // 错误!x是只读属性 ``` #### 4. 索引签名 当我们需要表示一个对象有任意数量的属性(但属性的类型一致)时,可以使用索引签名。 ```typescript interface StringDictionary { [key: string]: string; // 键为字符串,值为字符串 } const dict: StringDictionary = { key1: "value1", key2: "value2" }; ``` #### 5. 函数类型 接口也可以描述函数类型。 ```typescript interface SearchFunc { (source: string, subString: string): boolean; } let mySearch: SearchFunc; mySearch = function(src: string, sub: string): boolean { return src.search(sub) > -1; }; ``` #### 6. 类类型(实现接口接口可以用于强制一个类去符合某种契约。注意,接口描述的是类的公共部分,而不是私有部分。 ```typescript interface ClockInterface { currentTime: Date; setTime(d: Date): void; } class Clock implements ClockInterface { currentTime: Date = new Date(); setTime(d: Date) { this.currentTime = d; } } ``` #### 7. 构造器签名(引用[4]的疑问) 引用[4]中出现了构造器签名。在TypeScript中,接口可以描述构造函数类型。但是,当我们使用`new`关键字时,它描述的是类的构造函数的类型。这通常用于定义一些能够创建类的工厂函数。 示例: ```typescript interface ClockConstructor { new (hour: number, minute: number): ClockInterface; // 表示构造函数类型 } interface ClockInterface { tick(): void; } // 工厂函数,接收一个构造器和一个时间,创建一个实例 function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface { return new ctor(hour, minute); } // 定义一个类实现ClockInterface class DigitalClock implements ClockInterface { constructor(h: number, m: number) { } tick() { console.log("beep beep"); } } // 使用工厂函数创建实例 const digital = createClock(DigitalClock, 12, 17); ``` 在上面的例子中,`ClockConstructor`接口定义了一个构造器签名,它表示一个构造函数,该函数接受两个数字参数(hour和minute)并返回一个满足`ClockInterface`的实例。因此,当我们调用`createClock`时,第一个参数需要是一个构造函数,这个构造函数的类型就是`ClockConstructor`。 #### 8. 接口继承 接口可以相互继承,从而实现接口的复用。 ```typescript interface Shape { color: string; } interface Square extends Shape { sideLength: number; } const square: Square = { color: "red", sideLength: 10 }; ``` #### 9. 接口与类型别名(type)的区别 引用[2]提到了类型别名也可以实现类似接口的功能。它们的主要区别包括: - 接口可以多次声明并自动合并,而类型别名不能重复声明。 - 类型别名可以用于更复杂的类型,如联合类型、元组等,而接口主要描述对象形状。 - 接口可以通过继承扩展,而类型别名可以使用交叉类型(&)实现类似扩展。 #### 小结 TypeScript接口提供了一种强大的方式来定义对象、函数、类等的结构。它们支持多种特性,如可选属性、只读属性、索引签名、继承等,并且可以很好地与类结合使用(实现接口)。接口和类型别名虽然在某些情况下可以互换,但各有适用场景。 §§相关问题§§ 1. TypeScript接口和类型别名(type)有哪些具体区别? 2. 如何在接口中定义方法(函数)? 3. TypeScript接口是否可以描述数组类型? 4. 如何实现接口的继承与合并? </think>### TypeScript接口(interface)的使用与特性 接口(interface)是TypeScript的核心特性之一,用于定义对象的形状(shape),主要作用包括类型检查、代码约束和增强可读性。以下是核心使用方法和特性: #### 一、基本使用方法 1. **对象类型定义** 定义对象属性和方法的类型约束: ```typescript interface User { name: string; // 必需属性 age: number; email?: string; // 可选属性(使用?) } const user: User = { name: "Alice", age: 30 }; ``` 2. **函数参数约束** 确保函数参数符合特定结构: ```typescript function printUser(userObj: User) { console.log(userObj.name); } printUser({ name: "Bob", age: 25 }); // 正确 ``` #### 二、核心特性 1. **可选属性** 属性名后加`?`表示可选: ```typescript interface Config { color?: string; width?: number; } const config: Config = {}; // 允许缺少可选属性 ``` 2. **只读属性** 使用`readonly`防止属性被修改(类似const): ```typescript interface Point { readonly x: number; readonly y: number; } const p: Point = { x: 10, y: 20 }; p.x = 5; // 编译错误![^3] ``` 3. **索引签名** 定义动态属性名(常用于字典结构): ```typescript interface StringMap { [key: string]: string; // 键值均为字符串类型 } const map: StringMap = { key1: "value1", key2: "value2" }; [^3] ``` 4. **函数类型定义** 描述函数结构: ```typescript interface SearchFunc { (source: string, keyword: string): boolean; } const mySearch: SearchFunc = (src, kw) => src.includes(kw); ``` 5. **类实现接口** 强制类遵循特定契约: ```typescript interface ClockInterface { currentTime: Date; setTime(d: Date): void; } class Clock implements ClockInterface { currentTime: Date = new Date(); setTime(d: Date) { this.currentTime = d; } } [^4] ``` 6. **构造器签名** 定义构造函数类型(需使用`new`关键字): ```typescript interface ClockConstructor { new (hour: number, minute: number): ClockInterface; } [^4] ``` #### 三、高级特性 1. **接口继承** 使用`extends`实现接口复用: ```typescript interface Shape { color: string; } interface Square extends Shape { sideLength: number; } const square: Square = { color: "blue", sideLength: 10 }; ``` 2. **混合类型** 组合对象、函数和索引签名: ```typescript interface Counter { (start: number): string; interval: number; reset(): void; } ``` 3. **接口合并** 同名接口自动合并(声明合并): ```typescript interface Box { height: number; } interface Box { width: number; } const box: Box = { height: 5, width: 6 }; // 合并后需包含所有属性 ``` #### 四、接口 vs 类型别名(type) | 特性 | 接口(interface) | 类型别名(type) | |--------------------|-------------------------|----------------------| | 扩展方式 | `extends`继承 | `&`交叉类型 | | 合并 | 支持声明合并 | 不支持合并 | | 实现类 | `implements`支持 | 不支持类实现 | | 主要用途 | 对象形状约束 | 任意类型别名定义 | > 最佳实践:优先使用接口定义对象结构,复杂类型(联合、元组等)用类型别名[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值