You need to enable JavaScript to run this app. TypeScript联合类型在Swift中的等价实现(适配Alamofire JSON解析)
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript联合类型在Swift中的等价实现(适配Alamofire JSON解析)

Swift 中对应 TypeScript 联合类型的实现(适配 Alamofire JSON 解析场景)

Swift 原生没有 TypeScript 那种语法层面的原生联合类型,但在 Alamofire 依赖 Codable 做 JSON 解析的场景下,用带关联值的枚举自定义 Codable 实现,是类型安全、和现有流程兼容度最高的等价方案,完全匹配你给出的 TS 类型结构。

具体实现

第一步:定义所有子类型的 Codable 结构

先把 TS 里的各个独立接口转成 Swift 的 Codable 结构体:

// 对应 TS 定义的 Question
struct Question: Codable {
    let value: String
    let data: [String] // 对应 TS 中 [string] 的字符串数组类型
}

// 对应 TS 定义的 Advice
struct Advice: Codable {
    let type: String
    let data: AdvicePayload // 把 TS 里的内联 JSON 对象拆为独立结构更易维护
    struct AdvicePayload: Codable {
        let value: String
    }
}

第二步:用枚举实现联合类型,自定义解码逻辑

把 TS 中 Advice | Question | string 的联合约束,用枚举的不同关联值承载,同时自定义解码流程适配 JSON 解析:

// 对应 TS 中 data 字段的联合类型约束
enum CurrentItemData: Codable {
    case question(Question)
    case advice(Advice)
    case plainText(String)

    init(from decoder: Decoder) throws {
        // 取当前 data 字段的单值容器,做类型匹配
        let singleContainer = try decoder.singleValueContainer()

        // 按优先级依次尝试匹配支持的类型,匹配成功就直接赋值
        if let text = try? singleContainer.decode(String.self) {
            self = .plainText(text)
            return
        }
        if let question = try? singleContainer.decode(Question.self) {
            self = .question(question)
            return
        }
        if let advice = try? singleContainer.decode(Advice.self) {
            self = .advice(advice)
            return
        }

        // 所有类型都匹配失败,抛出标准解码错误
        throw DecodingError.typeMismatch(
            CurrentItemData.self,
            .init(
                codingPath: singleContainer.codingPath,
                debugDescription: "data 字段不属于支持的三种类型(字符串/Question/Advice)"
            )
        )
    }
}

// 对应 TS 定义的 CurrentItem
struct CurrentItem: Codable {
    let type: String
    let data: CurrentItemData
}

第三步:直接接入 Alamofire 流程

因为所有类型都遵循标准 Codable 协议,不需要额外适配,直接传给 Alamofire 的 responseDecodable 方法就能正常解析:

AF.request("你的接口地址")
    .responseDecodable(of: CurrentItem.self) { response in
        // 解析结果正常返回,取 data 值时可以根据枚举分支做对应处理
        switch response.result {
        case .success(let item):
            switch item.data {
            case .question(let q):
                print("Question 类型: \(q.value)")
            case .advice(let a):
                print("Advice 类型: \(a.data.value)")
            case .plainText(let text):
                print("纯字符串类型: \(text)")
            }
        case .failure(let err):
            print("解析失败: \(err)")
        }
    }

可选优化

如果你的后端接口约定 data 的具体类型完全由外层的 type 字段决定,可以把解码逻辑调整为优先读取 type 值做类型判断,不用盲目尝试所有子类型,解析效率和稳定性会更高。

不推荐的临时方案

  • 不要直接把 data 定义为 Any 类型:这种类型根本不遵循 Codable 协议,Alamofire 无法完成自动解析,运行时还容易出现类型转换崩溃
  • 尽量避免直接用第三方 AnyCodable 容器承载动态值:这类方案会丢失编译期类型检查,适合快速原型开发,正式项目里还是枚举的类型安全方案更可靠

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.08 01:15:04