Checking validity of string literal union type at runtime?

前端 未结 7 1522
孤独总比滥情好
孤独总比滥情好 2020-12-03 04:16

I have a simple union type of string literals and need to check it\'s validity because of FFI calls to \"normal\" Javascript. Is there a way to ensure that a certain variabl

7条回答
  •  庸人自扰
    2020-12-03 05:05

    You cannot call a method on a type, because types don't exist in runtime

    MyStrings.isAssignable("A"); // Won't work — `MyStrings` is a string literal
    

    Instead, create executable JavaScript code that will validate your input. It's programmer's responsibility to ensure the function does its job properly.

    function isMyString(candidate: string): candidate is MyStrings {
      return ["A", "B", "C"].includes(candidate);
    }
    

    Update

    As suggested by @jtschoonhoven, we can create en exhaustive type guard that will check if any string is one of MyStrings.

    First, create a function called enumerate that will make sure all members of the MyStrings union are used. It should break when the union is expanded in the future, urging you to update the type guard.

    type ValueOf = T[keyof T];
    
    type IncludesEvery =
      T extends ValueOf
        ? true
        : false;
    
    type WhenIncludesEvery =
      IncludesEvery extends true
        ? U
        : never;
    
    export const enumerate = () =>
      (...elements: WhenIncludesEvery): U => elements;
    

    The new-and-improved type guard:

    function isMyString(candidate: string): candidate is MyStrings {
      const valid = enumerate()('A', 'B', 'C');
    
      return valid.some(value => candidate === value);
    }
    

提交回复
热议问题