You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写适配继承顶级接口的通用TypeScript持久化函数

解决方案:实现通用的持久化动物类型转换函数

我们需要调整类型定义逻辑,让每个动物类型能明确区分未持久化和持久化状态,同时建立两者的关联,确保函数能精准完成类型转换。

1. 重构基础类型与动物类型

将动物接口改为泛型结构,通过persisted参数控制是否包含id属性,同时继承对应的基础接口:

interface UnpersistedAnimal {
    name: string;
}

interface PersistedAnimal extends UnpersistedAnimal {
    id: number;
}

// 泛型基础类型,通过persisted参数切换状态
type AbstractAnimal<T extends boolean = true> = T extends true ? PersistedAnimal : UnpersistedAnimal;

// 泛型Duck类型,继承对应状态的AbstractAnimal
interface Duck<T extends boolean = false> extends AbstractAnimal<T> {
    name: "Duck";
}

// 泛型Goose类型,同理
interface Goose<T extends boolean = false> extends AbstractAnimal<T> {
    name: "Goose";
}

现在可以直接用Duck<false>表示未持久化鸭子,Duck<true>表示持久化鸭子,TypeScript会自动校验属性合法性。

2. 实现通用的persistAnimal函数

定义类型工具统一转换逻辑,让函数接收任意未持久化动物类型,返回对应的持久化版本:

// 类型工具:将未持久化类型转换为持久化类型
type ToPersisted<T> = T extends AbstractAnimal<false> ? T & PersistedAnimal : never;

function persistAnimal<T extends AbstractAnimal<false>>(animal: T): ToPersisted<T> {
    const persisted = animal as ToPersisted<T>;
    persisted.id = Math.floor(Math.random() * 1000); // 模拟生成唯一ID
    return persisted;
}

3. 使用验证

测试代码完全符合预期:

// 未持久化鸭子,无id属性
const unpersistedDuck: Duck<false> = { name: "Duck" };
console.log(unpersistedDuck.id); // TypeScript提示错误:属性'id'不存在于类型'Duck<false>'上

// 持久化后得到带id的Duck类型
const persistedDuck = persistAnimal(unpersistedDuck);
console.log(persistedDuck.id); // 正常,类型为number
console.log(persistedDuck.name); // 类型保持为"Duck"

// Goose类型同理
const unpersistedGoose: Goose<false> = { name: "Goose" };
console.log(unpersistedGoose.id); // 错误提示
const persistedGoose = persistAnimal(unpersistedGoose);
console.log(persistedGoose.id); // 正常访问

关键优化点

  • 让动物类型本身成为泛型,明确关联两种状态,避免交叉类型的模糊性
  • 用类型工具ToPersisted统一转换逻辑,保证类型推断准确
  • 函数内部类型断言更精准,避免不必要的类型拓宽

内容的提问来源于stack exchange,提问作者tobias47n9e

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 14:15:34