How to represent Guid in typescript?

后端 未结 3 722
Happy的楠姐
Happy的楠姐 2020-12-15 20:55

let\'s say I have this C# class

public class Product
{
   public Guid Id { get; set; }
   public string ProductName { get; set; }
   public Decimal Price { g         


        
相关标签:
3条回答
  • 2020-12-15 21:18

    Guids are usually represented as strings in Javascript, so the simplest way to represent the GUID is as a string. Usually when serialization to JSON occurs it is represented as a string, so using a string will ensure compatibility with data from the server.

    To make the GUID different from a simple string, you could use branded types:

    type GUID = string & { isGuid: true};
    function guid(guid: string) : GUID {
        return  guid as GUID; // maybe add validation that the parameter is an actual guid ?
    }
    export interface Product {
        id: GUID;
        productName: string;
        price: number;
        level: number;
    }
    
    declare let p: Product;
    p.id = "" // error
    p.id = guid("guid data"); // ok
    p.id.split('-') // we have access to string methods
    

    This article has a bit more of a discussion on branded types. Also the typescript compiler uses branded types for paths which is similar to this use case.

    0 讨论(0)
  • 2020-12-15 21:33

    Another alternative is using following NPM package:

    guid-typescript which you can find here: https://www.npmjs.com/package/guid-typescript

    Then it will be just like this:

    import { Guid } from "guid-typescript";
    
    export class Product {
        id: Guid;
        productName: string;
        price: number;
        level: number;
    }
    
    0 讨论(0)
  • 2020-12-15 21:40

    For most of my use cases, I need to accept a deserialized string that comes from an API, but also generate new ids and validate them once they're on the client.

    Both of the previous answers are great & each tackle a piece of the problem, where this gist combines the typing from the accepted answer and the spirit of the guid-typescript package: https://gist.github.com/dperish/b9b2bbc6f10c686921c0f216bfe4cb40

    class GuidFlavoring<FlavorT> {
      // tslint:disable-next-line: variable-name
      _type?: FlavorT;
    }
    
    /** A **guid** type, based on **string** */
    type GuidFlavor<T, FlavorT> = T & GuidFlavoring<FlavorT>;
    
    /** A **guid**-flavored string primitive, supported by factory methods in the **Guid** class
     */
    export type guid = GuidFlavor<string, 'guid'>;
    
    /** A container for factory methods, which support the **guid** type */
    export class Guid {
      /** Specifies the RegExp necessary to validate **guid** values */
      private static validator: RegExp = new RegExp(
        '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$',
        'i'
      );
    
      /** Generates a random, hyphenated **guid** value */
      static newGuid = (): guid =>
        [
          Guid.generateGuidSegment(2),
          Guid.generateGuidSegment(1),
          Guid.generateGuidSegment(1),
          Guid.generateGuidSegment(1),
          Guid.generateGuidSegment(3),
        ].join('-');
    
      /** Generates a new **guid**, with the empty/least possible value
       * @returns {guid} 00000000-0000-0000-0000-000000000000
       */
      static empty = (): guid => '00000000-0000-0000-0000-000000000000';
    
      /** Generates a new **guid**, with the full/greatest possible value
       * @returns {guid} ffffffff-ffff-ffff-ffffffffffff
       */
      static full = (): guid => 'ffffffff-ffff-ffff-ffffffffffff';
    
      /** Evaluates whether the supplied **guid** is equal to the empty/least possible value */
      static isEmpty = (value: guid) => value === Guid.empty();
    
      /** Evaluates whether the supplied *guid* is equal to the empty/greatest possible value */
      static isFull = (value: guid) => value === Guid.full();
    
      /** Evaluates whether the supplied value is a valid **guid** */
      static isValid = (value: string | guid): boolean =>
        Guid.validator.test(value);
    
      /** Generates a specified number of double-byte segements for **guid** generation  */
      private static generateGuidSegment(count: number): string {
        let out = '';
        for (let i = 0; i < count; i++) {
          // tslint:disable-next-line:no-bitwise
          out += (((1 + Math.random()) * 0x10000) | 0)
            .toString(16)
            .substring(1)
            .toLowerCase();
        }
        return out;
      }
    }
    
    0 讨论(0)
提交回复
热议问题