TS 使用泛型和 typeof约束参数

在 TypeScript(TS)中,泛型和 typeof 是两个强大的工具,可以帮助你创建更灵活和类型安全的代码。泛型允许你定义函数、接口或类时不具体指定类型,而 typeof 则用于获取一个变量或值的类型。

泛型

泛型允许你在定义函数、接口或类时,不指定具体的类型,而是在使用时指定。这样可以让你的代码更加灵活和可复用。

例如,定义一个简单的泛型函数:

typescript 复制代码
function identity<T>(arg: T): T {
    return arg;
}

// 使用泛型函数
const number = identity<number>(42); // 类型是 number
const text = identity<string>("Hello"); // 类型是 string

typeof

typeof 操作符用于获取一个变量或属性的类型。这在很多场景下都非常有用,比如当你需要根据一个现有变量的类型来定义另一个变量的类型时。

typescript 复制代码
const someNumber = 42;
type NumberType = typeof someNumber; // NumberType 是 number

const someString = "Hello";
type StringType = typeof someString; // StringType 是 string

泛型与 typeof 结合使用

有时候你可能需要定义一个泛型,但又要约束这个泛型参数的类型,使其只能是某个特定类型或某个特定对象的类型。这时,你可以将 typeof 与泛型结合使用。

约束泛型参数为特定对象的类型

假设你有一个对象,并希望定义一个函数,这个函数接受一个与这个对象类型相同的参数:

typescript 复制代码
const config = {
    apiUrl: "https://api.example.com",
    timeout: 5000
};

function printConfig<T extends typeof config>(cfg: T) {
    console.log(cfg.apiUrl);
    console.log(cfg.timeout);
}

// 正确使用
printConfig(config);

// 错误使用(如果尝试传入一个与 config 类型不兼容的对象)
// printConfig({ apiUrl: "https://wrong-url.com" }); // Error: Property 'timeout' is missing in type '{ apiUrl: string; }' but required in type 'typeof config'.

在这个例子中,泛型 T 被约束为 typeof config,这意味着 T 必须是与 config 相同类型的对象。

泛型与 typeof 结合用于类和方法

你也可以在类和方法中使用这种技巧:

typescript 复制代码
interface Config {
    apiUrl: string;
    timeout: number;
}

const defaultConfig: Config = {
    apiUrl: "https://api.example.com",
    timeout: 5000
};

class ApiClient<T extends typeof defaultConfig> {
    private config: T;

    constructor(config: T) {
        this.config = config;
    }

    getConfig() {
        return this.config;
    }
}

const client = new ApiClient(defaultConfig);
console.log(client.getConfig().apiUrl); // 输出: https://api.example.com

在这个例子中,ApiClient 类接受一个泛型参数 T,这个参数被约束为 typeof defaultConfig 的类型。这样,ApiClient 的实例将只能接受与 defaultConfig 相同类型的配置对象。

总结

通过将泛型与 typeof 结合使用,你可以创建更灵活和类型安全的 TypeScript 代码。这种技巧在处理配置对象、依赖注入和其他需要类型约束的场景中特别有用。

相关推荐
退休倒计时11 小时前
【每日一题】LeetCode 142. 环形链表 II TypeScript
算法·leetcode·链表·typescript
夕夕木各16 小时前
探究 TypeScript 类型体操里的 Equal 和 IsAny
typescript·源码阅读
GuWenyue16 小时前
10分钟搞定TodoList实战!从0搭建Bun+TS的RESTful接口服务
前端·typescript·bun
rising start18 小时前
九、vue3 组件通信:全场景详解
前端·vue.js·typescript
向上的车轮18 小时前
TypeORM 1.0 正式发布:新一代 Node.js ORM 框架全面解析
typescript·node.js·typeorm
ZengLiangYi1 天前
测试策略:单元测试 + 集成测试怎么写
javascript·typescript·node.js
颂love2 天前
Vue的两大生态以及组件通信
前端·javascript·vue.js·typescript
hhb_6182 天前
TypeScript泛型实战:企业级请求封装全解析
javascript·ubuntu·typescript
crack_comet2 天前
修复 Claude Code TypeScript LSP 在 Windows 上启动失败的问题
windows·typescript·里氏替换原则
惢雨2 天前
ts中的特殊符号说明并举例,如 ?. 、?:、??等
前端·typescript