TypeScript & runtime type-checking, simple solution in 2020 [closed]

时光怂恿深爱的人放手 提交于 2020-11-27 04:55:53

问题


As we all know, TypeScript type-checks only at compile-time.

There are couple of existing approaches to add runtime checks, such as io-ts, but I'm left to wonder if there is a simpler way.

For example a Babel plugin that would transpile this:

type Todo = {
  userId: number;
  id: number;
  title: string;
  completed: boolean;
}

const resp = await fetch("https://jsonplaceholder.typicode.com/todos/1");

const data = await resp.json();

assert(data typeof Todo);

to that:

const __TodoType = {
  userId: Number;
  id: Number;
  title: String;
  completed: Boolean;
};
const __isTodoType = obj => (
  obj &&
  obj.constructor === Object &&
  Object.keys(obj).length === Object.keys(__TodoType).length &&
  Object.entries(obj)
    .every(([prop, val]) =>
      __TodoType[prop] && val &&
      __TodoType[prop] === val.constructor)
);

const resp = await fetch("https://jsonplaceholder.typicode.com/todos/1");

const data = await resp.json();

assert(__isTodoType(data));

This would be a super simple solution and would cover many (if not most) uses cases. AFAICT, this would be enough for asserting serialization / data fetching.

Has someone managed to build such Babel plugin?

Edit - I know the existing libraries such as io-ts but I'm looking for something much simpler. The Babel Plugin I'm showcasing is vastly simpler (from the perspective of the plugin user) than anything else I've seen so far. I'm not sure why this hasn't been done before.


回答1:


I was frustrated by this as well and ended up writing my own type guard generator called ‛ts-type-checked‛ available as an NPM module. It is a TypeScript transform that generates type guards based on your types.




回答2:


Give typescript-runtime-types a try. I don't know how or if this works with Babel, but there is a small section on using it with Webpack and awesome-typescript-loader. I think it does what you're looking for, although the only examples it shows are with interfaces, which may mean you aren't allowed to nest types or use & or | or Pick or other complex type annotations. If that's true, you will just need to use io-ts.




回答3:


I don't know any cool tool to do that automatically but I can tell you what I use to validate types on runtime: AJV - https://github.com/ajv-validator/ajv

It's not ideal because you need to generate your json schemas for each type, but you can automate that with typescript-json-schema (https://github.com/YousefED/typescript-json-schema#readme)

Hope this helps!




回答4:


TySheMo https://github.com/tangshuang/tyshemo

A javascript runtime data type checking system ...

I have been using this library for front-end api guarding

Sometimes back-end gives me a null or an empty object {} breaking down the page with ... cannot read property xxx of null ...

Write an interceptor for api's responses using this, you can capture the dirty data no matter how deep the data structure of res is

Personally, I have revised the source code of TySheMo and it really is a great piece of work




回答5:


Typescript's instanceof type guard checks the constructor function, but I don't think it checks all the keys as well. Still, in most cases, it should be enough.

Working with external API, you can use class-validator package for more detailed validation, and class-transformer-validator if you want to transform plain objects (for example, parsed from JSON) to your classes.




回答6:


I'm using io-ts. You only need to write once for type and runtime checking.



来源:https://stackoverflow.com/questions/61573617/typescript-runtime-type-checking-simple-solution-in-2020

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!