【问题标题】:io-ts parse array of Eithers/Validationsio-ts 解析 Eithers/Validations 数组
【发布时间】:2021-09-18 22:30:30
【问题描述】:

我正在尝试解析返回用户数组的 API 响应。我发现即使数组中的一个元素验证失败,整个编解码器也会返回错误。我希望错误留在数组中,这样我就可以拥有类似Array<Either<E, User>> 的东西。我的 API 的响应看起来像这样

{
    "success": true,
    "result": [
        {
            "name": "Jo Smith",
            "email": "jo@jo.jo",
            "preferredName": null
        },
        {
            "name": "Robert",
            "email": "rob@rob.rob",
            "preferredName": "Rob"
        }
    ]
}

{
    "success": false,
    "error": "Something went wrong"
}

这是我的编解码器

import * as t from "io-ts";

const userV = t.type({
    name: t.string,
    email: t.string,
    preferredName: t.union([t.string, null]),
});

const successV = t.type({
    success: t.literal(true),
    result: t.array(userV),
});

const errorV = t.type({
    success: t.literal(false),
    error: t.string,
});

const responseV = t.union([successV, errorV]);

现在,如果由于某种原因,我们收到一个电子邮件为 null 的用户,则整个响应都会失败。如果我想列出正确解析的用户并在我的 UI 中仅为错误用户显示错误消息怎么办?显而易见的(天真的?)方法是使所有属性都可以为空,但有更好的方法吗?我还考虑通过首先返回 t.array(t.unknown) 分两步解析响应,但我不确定这会是什么样子

【问题讨论】:

  • 您是否尝试在您的userV 对象中使用option{email: option(t.string)}
  • option 来自哪里?另外,我确实希望该对象的验证失败,但不是整个 responseV 失败
  • 只写:google 中的 io-ts 选项
  • 来自 io-ts-types,明白了。虽然对我没有帮助。如果字段错误,我确实希望验证失败(在我的现实生活中,我有更多可能失败的字段)。我需要的是让单个 User 对象失败,留下其他适当的对象。所以我认为我需要 result 成为一个 Eithers 数组,而不是一个充满选项的对象数组
  • 我希望能帮助你更多,但我不是 io-ts 方面的专家

标签: typescript validation parsing fp-ts


【解决方案1】:

你可以:

import * as t from "io-ts";
import * as F from 'fp-ts/function'
import * as E from 'fp-ts/Either'
import * as A from 'fp-ts/Array'

const users: unknown[] = [{
  name: 'badUser',
  email: null,
  preferredName: 'hey'
}, {
  name: 'goodUser',
  email: 'ihaveemail@mail.com',
  preferredName: 'okay'
}]

const result = F.pipe(
  users,
  A.map(userV.decode),
  A.separate
)

A.separate 是一个函数,它接受 Array<Either<A, B>> 并返回一个对象,其中所有 Lefts 都在 left 字段中,Rights 在 right 字段中。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-17
  • 1970-01-01
  • 1970-01-01
  • 2020-03-26
  • 2021-05-10
  • 2016-04-18
  • 1970-01-01
相关资源
最近更新 更多