TypeScript 接口(Interface)完全笔记

一、接口概述 🎯

接口的作用:约束 对象函数 的类型结构

接口就像一份契约,规定了数据应该有的形状和行为


二、对象类型接口 📦

基础用法

// 定义对象接口
interface Person {
    name: string;
    age: number;
}

// 使用接口约束对象
let alice: Person = {
    name: "Alice",
    age: 25
};

⚠️ 重点:多余属性检查

当直接给函数传参对象自变量时,TypeScript 会进行多余属性检查

interface Person {
    name: string;
    age: number;
}

function greet(person: Person) {
    console.log(`Hello, ${person.name}`);
}

// ❌ 错误:对象自变量中有多余的属性 'id'
greet({
    name: "Alice",
    age: 25,
    id: 1  // 多余属性
});

// ✅ 解决方案一:类型断言
greet({
    name: "Alice",
    age: 25,
    id: 1
} as Person);

// ✅ 解决方案二:索引签名
interface Person {
    name: string;
    age: number;
    [prop: string]: any;  // 允许任意额外属性
}

// ✅ 解决方案三:定义变量(绕过多余属性检查)
let alice = {
    name: "Alice",
    age: 25,
    id: 1
};
greet(alice);  // ✅ 变量传参不会触发出多余属性检查

对象接口的高级特性

interface User {
    readonly id: number;      // 只读属性
    name: string;
    age?: number;             // 可选属性
    [key: string]: unknown;   // 索引签名(允许额外属性)
}

三、函数类型接口 🎭

函数定义的四种方式

方式一:直接定义(最基础)

function add(x: number, y: number): number {
    return x + y;
}

方式二:变量定义函数类型

// 定义函数类型的变量
let add: (x: number, y: number) => number;

// 实现
add = (x, y) => {
    return x + y;
};

// 或者直接赋值
let multiply: (x: number, y: number) => number = (x, y) => x * y;

方式三:类型别名定义

// 定义类型别名
type Add = (x: number, y: number) => number;

// 使用类型别名
let add: Add = (x, y) => {
    return x + y;
};

// 更简洁的写法
let subtract: Add = (x, y) => x - y;

方式四:接口定义函数类型 ⭐

// 使用接口定义函数类型
interface Add {
    (x: number, y: number): number;
}

// 使用
let add: Add = (x, y) => {
    return x + y;
};

// 也可以定义更复杂的函数接口
interface MathOperation {
    (x: number, y: number): number;
    description?: string;  // 函数可以有属性
}

const multiply: MathOperation = (x, y) => x * y;
multiply.description = "乘法运算";

四、四种函数定义方式对比 📊

方式 语法 适用场景 优点
直接定义 function add(x: number): number {} 简单函数 直观、简单
变量定义 let add: (x: number) => number 函数表达式 灵活
类型别名 type Add = (x: number) => number 复用函数类型 可复用、可读性好
接口定义 interface Add { (x: number): number } 复杂函数类型 可扩展、可合并

完整示例:所有方式对比

// 1. 直接定义
function fn1(x: number, y: number): number {
    return x + y;
}

// 2. 变量定义
let fn2: (x: number, y: number) => number = (x, y) => x + y;

// 3. 类型别名
type Fn3 = (x: number, y: number) => number;
let fn3: Fn3 = (x, y) => x + y;

// 4. 接口定义
interface Fn4 {
    (x: number, y: number): number;
}
let fn4: Fn4 = (x, y) => x + y;

五、接口的其他应用 🚀

1. 类类型接口

interface ClockInterface {
    currentTime: Date;
    setTime(d: Date): void;
}

class Clock implements ClockInterface {
    currentTime: Date = new Date();
    
    setTime(d: Date): void {
        this.currentTime = d;
    }
}

2. 接口继承

interface Animal {
    name: string;
}

interface Dog extends Animal {
    breed: string;
}

let myDog: Dog = {
    name: "Rex",
    breed: "German Shepherd"
};

3. 混合类型接口

interface Counter {
    (start: number): string;    // 函数调用
    interval: number;            // 属性
    reset(): void;               // 方法
}

function getCounter(): Counter {
    let counter = function(start: number) {
        return `Count: ${start}`;
    } as Counter;
    
    counter.interval = 1000;
    counter.reset = () => {};
    
    return counter;
}

📌 核心要点总结

1. 接口的三种主要用途

  • ✅ 约束对象的类型
  • ✅ 约束函数的类型
  • ✅ 约束的结构

2. 对象接口注意事项

  • 多余属性检查:直接传对象自变量时会触发
  • 绕过方法:类型断言、索引签名、先赋值给变量
  • 属性修饰符readonly(只读)、?(可选)

3. 函数接口四种定义方式

  1. 直接定义:最基础的方式
  2. 变量定义:适合函数表达式
  3. 类型别名:适合复用函数类型
  4. 接口定义:适合复杂或需要扩展的函数类型

4. 选择建议

  • 简单函数:直接定义
  • 需要复用:类型别名
  • 复杂结构:接口定义
  • 回调类型:变量定义或类型别名

💡 小贴士:定义函数类型时,优先使用类型别名type)因为它更简洁;需要扩展或合并时使用接口interface

posted @ 2026-03-12 19:41  哥哦狗子  阅读(38)  评论(0)    收藏  举报