1

运行时数据是否可以指定运行时类型检查的类型?希望使用 io-ts?

一个switch语句创建多个位置来添加新类型。查找对象属性,例如types[runtime.type]创建编译时类型检查错误。值可能是未定义的。

运行时数据:

[{label:"user", userid:1}, {label:"post", body:"lipsum"}]

类型:

type User = {
  label: 'user'
  userid: number
}

type Delete = {
  label: 'post'
  body: string
}

检查类型后,我还想在通用实现中使用数据:

function save<A>(data:A) {
  mutate<A>(data)
  validate<A>(data)
  send<A>(data)
}
4

2 回答 2

0

如果您的标签在所有类型中都是通用的,那么如果您针对要处理的每种情况进行测试,则可以使用类型保护轻松处理此问题。

对于标记为返回的函数x is y,如果它返回true,则编译器知道在truean 的部分中if,变量是该类型,而在 else 中,不是该类型。

const data = [{label:"user", userid:1}, {label:"post", body:"lipsum"}]

type User = {
  label: 'user'
  userid: number
}

function isUser(u: { label: string }): u is User {
  return u.label === 'user';
}

type Delete = {
  label: 'post'
  body: string
}

function isDelete(d: { label: string }): d is Delete {
  return d.label === 'post';
}

for (const datum of data) {
  if (isUser(datum)) {
    console.log(`User with userid of ${datum.userid}`);
  } else if (isDelete(datum)) {
    console.log(`Delete with body of ${datum.body}`);
  }
}

TypeScript Playground
用户定义类型保护

于 2020-09-04T16:46:00.213 回答
0

这被称为相关记录类型,在 TypeScript 社区中有相当多的讨论。我的方法是将相关记录检查移至运行时:

https://github.com/microsoft/TypeScript/issues/30581#issuecomment-686621101

https://repl.it/@urgent/runtime-fp-ot

步骤1

创建一个包含Prop所有允许属性的通用接口。

interface Prop {
  label: "user" | "post",
  userid: string,
  body: string
}

这确实会阻止类型特定的属性,并且您可能会发生冲突。user.id想成为一个numberpost.id想成为一个string。对我来说没什么大不了的。考虑一个特定于您的类型的不同属性名称,接受那里的内容,或者如果您喜欢冒险尝试添加维度Props并按类型索引。

第2步

创建标签映射到运行时解码器。在打字稿中,我使用了一个类,因此我可以通过不同的文件对其进行扩展:

class Decoder {
  user: userDecode,
  post: postDecode
}

第 3 步

创建一个函数,该函数接受 props,从类原型中查找解码器,并执行运行时解码

(props:Props) => Decoder.prototype[props.label].decode(props as any)

io-ts 需要any在严格模式下扩大。您还需要一个props.label存在于Decoder

第4步

创建类似的功能图来运行。如果您在运行时解码后调用它们,您就知道运行时正在传递有效值。

缺点

  1. 比写出和管理 switch 语句要复杂得多。TypeScript 类型switch自动缩小。
  2. 财产冲突。没有添加工作的类型没有特定属性。
  3. 需要手动检查类型是否存在。switch将忽略,并使用默认情况

优点

  1. 您可以永久关闭运行时处理。隔离,如果您需要添加对不同运行时类型的支持,则无需打开该代码。
  2. 在为不同的运行时类型创建支持时,例如pageor file,类似 babel 文件的东西可以自动导入新文件。
  3. 适合版本控制和开发人员访问权限。可以开放新类型供公众提交。核心处理可以保持关闭。所以你有一个 DSL 的开始。
于 2020-09-03T17:33:02.700 回答