typescript 如果对象没有声明的属性,则使用io-ts进行严格验证

drnojrws  于 2023-03-19  发布在  TypeScript
关注(0)|答案(2)|浏览(151)

我正在使用io-ts为一个API做输入验证。我需要确保在requirement对象中没有未声明的属性。
例如,如果我将request的接口定义为:

const Request = t.type({
  id: t.string,
  name: t.string
});

并且如果输入如下:

const req = { 
  id: 'r1',
  name: 'req 1',
  description: 'desc' // property "description" is not declaration on Request type.
}

然后我做如下验证:

const r = Request.decode(req);

if (isLeft(r)) {
    console.log(PathReporter.report(r));
} else {
    console.log("validate success");
}

我希望输出是未声明属性的错误。但它成功了。
有没有办法做基于io-ts的严格验证?

qvk1mo1f

qvk1mo1f1#

我找到了这个问题的解决方法。
https://github.com/gcanti/io-ts/issues/322#issuecomment-513170377

import * as t from 'io-ts';
import { chain } from 'fp-ts/Either'
import { pipe } from 'fp-ts/function';

function getExcessProps(props: t.Props, r: Record<string, unknown>): string[] {
  const ex = []
  for (const k of Object.keys(r)) {
    if (!props.hasOwnProperty(k)) {
      ex.push(k)
    }
  }
  return ex
}

export function excess<C extends t.InterfaceType<t.Props>>(codec: C): C {
  const r = new t.InterfaceType(
    codec.name,
    codec.is,
    (input, c) => pipe(
      t.UnknownRecord.validate(input, c),
      chain(result => {
        const ex = getExcessProps(codec.props, result)
        return ex.length > 0
          ? t.failure(
            input,
            c,
            `Invalid value ${JSON.stringify(input)} supplied to : ${
              codec.name
            }, excess properties: ${JSON.stringify(ex)}`
          )
          : codec.validate(input, c)
      })),
    codec.encode,
    codec.props
  )
  return r as C;
}
l7wslrjt

l7wslrjt2#

严格来说,这并不是对您问题的回答,但io-ts也提供了strict,它将忽略输入对象中未在编解码器上声明的任何属性。(而type将保留此类附加属性。)strictexact(type(...))的别名。
当然,这并不能真正帮助您进行验证,但是在相关的用例中,能够剥离附加属性可能会有所帮助。

相关问题