首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >跨界面式保护装置

跨界面式保护装置
EN

Stack Overflow用户
提问于 2022-07-14 09:50:16
回答 1查看 54关注 0票数 2

假设schema对象验证data对象。

有什么黑魔法可以让我们缩小data属性在schema-based类型保护之后的类型吗?

片段值一千字:

代码语言:javascript
复制
function validate(data: Data, schema: Schema) {}

interface Data {
  [key: string]: number | string | undefined;
}

interface Schema {
  properties: {
    [key: string]: { type: "number" | "string" } | undefined;
  };
}

// Just for demo purposes: we don't know its exact shape until run time.
const schema: Schema = {
  properties: {
    firstName: {
      type: "string",
    },
  },
};

// Idem.
const data: Data = {
  firstName: "John",
};

validate(data, schema); // What kind of magic could happen here...

if (schema.properties.firstName?.type === "string") {
  const firstName: string = data.firstName; // ...so that there's no error here?
}

游乐场

我正在考虑将Schema转换为一个具有自定义getter函数的类,该类依赖于asserts关键字来相应地键入data属性。(1)我不确定这是否可行;(2)也许有更好的办法。

有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-14 19:25:37

不幸的是,类型记录的类型系统不足以表示schema的属性和data的属性之间的任意关联。它需要类似于微软/打字稿#30581中描述的关联联合,以及每种可能的对象类型的“无限”联合,这就像微软/打字稿#14466中所要求的存在类型.但是TypeScript并不直接支持这两种方法。

我想说的是,您需要将schemadata都封装在一个对象中,这会暴露一些方法来获取模式类型和属性值对的歧视结合。可能是这样的:

代码语言:javascript
复制
function validate(data: Data, schema: Schema) {
  // do validation, and then
  return function prop(k: string) {
    return { type: schema.properties[k]?.type, data: data[k] } as
      { type: "number", data: number } |
      { type: "string", data: string } |
      { type: undefined, data: undefined }
  }
}

因此,当您调用validate(data, schema)时,您将得到一个验证函数:

代码语言:javascript
复制
const vf = validate(data, schema);

对于任何给定的属性,都可以调用此函数:

代码语言:javascript
复制
const firstNameProp = vf("firstname");

它是类型/数据值的受歧视的联合:

代码语言:javascript
复制
/* const firstNameProp: {
    type: "number";
    data: number;
} | {
    type: "string";
    data: string;
} | {
    type: undefined;
    data: undefined;
} */

它可以以您想要的方式检查:

代码语言:javascript
复制
if (firstNameProp.type === "string") {
  const firstName: string = firstNameProp.data;
} else {
  firstNameProp.data // number | undefined now
}

这不是很好,但至少可以在类型系统中表示。

操场链接到代码

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72978558

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档