Quartett 9: Allegro | Typoskript

Bei der Erstellung der Bibliothek zur Datenvalidierung quartetwurden folgende Orientierungspunkte gesetzt:



In diesem Artikel möchte ich mich quartetauf TypeScript konzentrieren.


Motivation


Wir arbeiten an unseren Projekten mit TypeScript. Als ich diese Bibliothek erstellte, wollte ich, dass die Person, die TypeScript kennt, das Quartett nicht als etwas völlig Neues für ihn lernt , sondern in dieser Bibliothek erkennt, was er bereits weiß.


Benutzerdefinierte Typschutzvorrichtungen


Betrachten Sie ein Beispiel. Wir fordern Daten über den Benutzer mit der API an. Wir gehen davon aus, dass sie vom folgenden Typ sind:


interface User {
  id: string;
  name: string;
  gender: "male" | "female";
  age: number;
  phoneBook: {
    [name: string]: string;
  };
}

Was ich von der Validierungsfunktion erhalten möchte:


const probablyUser: unkown = { ... }

if (checkUser(probablyUser)) {
    // probablyUser has type User
    console.log(probablyUser.name)
} else {
    // probablyUser has type unkown
    throw new Error('Probably User has not type User')
}

Um dieses Ziel zu erreichen, werden benutzerdefinierte Typschutzvorrichtungen verwendet .


Das heißt, die Funktionsdeklaration sollte folgendermaßen aussehen:


function checkUser(probablyUser: any): probablyUser is User {
  // ...
}

Verwenden wir quartet, um eine solche Funktion zu erstellen:


import { v } from "quartet";

const checkUser = v({
  id: v.string,
  name: v.string,
  gender: ["male", "female"],
  age: v.number
  phoneBook: {
    [v.rest]: v.string,
  }
});

Nachdem wir einen solchen Code geschrieben haben, erhalten wir eine Funktion, die nicht TypeGuard ist:


chechUser: (value: any) => boolean;

Um TypeGuard zu erstellen, muss deklarativ angegeben werden, welcher Typ von dieser Funktion validiert wird. Dies geschieht folgendermaßen:


const checkUser = v<User>({
  // ...
});

Zusammenfassend:


chechUser: (value: any) => value is User

Zu diesem Artikel gibt es zwei Punkte:


Garantie


Die Tatsache, dass der Entwickler angeben kann, welcher Typ von der Schaltung validiert wird, kann alarmieren, da es durchaus möglich ist, wie folgt zu schreiben:


const checkNumber = v<number>({ name: v.string });
// checkNumber: (value: any) => value is number

{ name: string }, , number.


. ( ) , — "" .


, .


, v. :


const v: <T>(schema: Schema) => (value: any) => value is T;

.


, TypeGuard .


:


const v: <T = any>(schema: Schema) => (value: any) => value is T;

, — never:


const checkNumber = v(v.number);
const value: any = "123";

if (!checkNumber(value)) {
  // value has type never
}

, , .


, T any , T === any, .


- :


const v: <T = any>(
  schema: Schema
) => IfAny<T, (value: any) => boolean, (value: any) => value is T>;

type IfAny<T,A,B> = // ...

— , :


T — any


:


type IfAny<T, A, B> = true extends T
  ? "1" extends T
    ? 1 extends T
      ? {} extends T
        ? (() => void) extends T
          ? null extends T
            ? A
            : B
          : B
        : B
      : B
    : B
  : B;

, , : boolean | number | string | object | function | null any.


TypeScript


, , TypeScript'a .


@hapi/joi ajv, User.


Text Compare .


quartet


const checkUser = v({
  id: v.string,
  name: v.string,
  gender: ["male", "female"],
  age: v.number
  phoneBook: {
    [v.rest]: v.string,
  }
})

Bild


- : 24


hapi/joi


const schema = j.object({
  id: j.string().required(),
  name: j.string().required(),
  gender: j
    .string()
    .valid("male", "female")
    .required(),
  age: j.number().required(),
  phoneBook: j.object().pattern(/.*/, j.string())
});

Bild


, , 118 .


ajv


const checkUser = a.compile({
  type: "object",
  required: ["id", "name", "gender", "age", "phoneBook"],
  properties: {
    id: { type: "string" },
    name: { type: "string" },
    gender: { type: "string", enum: ["male", "female"] },
    phoneBook: {
      type: "object",
      additionalProperties: {
        type: "string"
      }
    }
  }
});

Bild


, 146 .


:


Bild


TypeScript. , , , .



TypeGuard — , .


TypeScript . — .


All Articles