Enforce that an array is exhaustive over a union type

后端 未结 2 1465
长发绾君心
长发绾君心 2021-01-13 20:23

Given a strongly-typed tuple created using a technique such as described here:

const tuple = (...args: T) => args;
const furnitu         


        
2条回答
  •  半阙折子戏
    2021-01-13 20:54

    I have other proposition

    type RemoveFirstFromTuple = 
      T extends [] ? undefined :
      (((...b: T) => void) extends (a: any, ...b: infer I) => void ? I : [])
    
    const tuple = (...args: T) => args;
    
    type FurnitureUnion = 'chair' | 'table' | 'lamp';
    type FurnitureTuple = ['chair', 'table' , 'lamp'];
    
    type Check> = {
      "error": never,
      "next": Check>,
      "exit": true,
    }[Tuple extends [] ? "exit" : Tuple[0] extends Union ? "next" : "error"];
    
    type R = Check; // true
    type R1 = Check<'chair' | 'lamp' | 'table', FurnitureTuple>; // true
    type R2 = Check<'chair' | 'lamp' | 'table', ['chair', 'table' , 'lamp', 'error']>; // nerver
    

    Remove from tuple takes tuple and return tuple without first element (will be needed later)

    Check will iterate on Tuple. Each step can return never when Tuple[0] don't extend Union, exit when input tuple is empty and next when Tuple[0] extends Union. In next step we recursive call Check but first we remove first element from Tuple by previous util

    Playground

提交回复
热议问题