Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 强制数组在联合类型上是穷举的_Typescript - Fatal编程技术网

Typescript 强制数组在联合类型上是穷举的

Typescript 强制数组在联合类型上是穷举的,typescript,Typescript,给定使用以下技术创建的强类型元组: 如何创建一个类型,以确保家具只包含家具联合中的每个类型 目标是能够在设计时创建这样一个数组,如果Furniturechange,它就会失败;理想的语法可能如下所示: const furniture = tuple<Furniture>('chair', 'table', 'lamp') const furniture=tuple('椅子'、'桌子'、'灯') 我还有其他建议 类型RemoveFirstFromTuple= T扩展[]?未定义: (

给定使用以下技术创建的强类型元组:

如何创建一个类型,以确保
家具
只包含
家具
联合中的每个类型

目标是能够在设计时创建这样一个数组,如果
Furniture
change,它就会失败;理想的语法可能如下所示:

const furniture = tuple<Furniture>('chair', 'table', 'lamp')
const furniture=tuple('椅子'、'桌子'、'灯')

我还有其他建议

类型RemoveFirstFromTuple=
T扩展[]?未定义:
(((…b:T)=>void)扩展(a:any,…b:inferi)=>void?I:[])
常量元组=(…args:T)=>args;
类型FurnitureUnion=‘椅子’|‘桌子’|‘灯’;
类型FurnitureTuple=[‘椅子’、‘桌子’、‘灯’];

类型检查有很多方法可以做到这一点,但对你来说可能有点混乱。这里的两个绊脚石是缺少和。以下是我的解决方案:

type Furniture = 'chair' | 'table' | 'lamp' | 'ottoman';

const exhaustiveStringTuple = <T extends string>() =>
  <L extends T[]>(
    ...x: L & ([T] extends [L[number]] ? L : [
      Error, "You are missing ", Exclude<T, L[number]>])
  ) => x;

const missingFurniture = exhaustiveStringTuple<Furniture>()('chair', 'table', 'lamp');
// error, [string, string, string] is not assignable to parameter of type
// ["chair", "table", "lamp"] & [Error, "You are missing", "ottoman"]

const extraFurniture = exhaustiveStringTuple<Furniture>()(
    'chair', 'table', 'lamp', 'ottoman', 'bidet');
// error, "bidet" is not assignable to a parameter of type 'Furniture'

const furniture = exhaustiveStringTuple<Furniture>()('chair', 'table', 'lamp', 'ottoman');
// okay

另一个问题是,当您遗漏一个必需的参数时,您得到的错误仅供参考,它在严格的条件下不起作用。我不建议使用像这样的递归类型别名,我相信这是积极劝阻,可能不会在未来工作。我同意这是不可读的解决方案。谢谢你的提示与严格模式,我修复它不工作。我不确定TS的未来。在microsoft roadmap上没有提到破坏更改。有关更多信息,请参阅。你在
检查
中所做的事情被明确地给出了一个答案,这真是太棒了。我必须承认,当我写这个问题的时候,我绝对是在欺骗你,因为我是你的经典打字解决方案的超级粉丝。所以我只需要确定双重调用是否比我一直在做的更糟糕,例如,
const furniture:{[key in furniture]:true}={chair:true,table:true,lamp:true}。我认为这样更好;我关心顺序,使用一个我真正想要的是一个有序集的对象似乎是错误的,从那时起,我不得不(理论上)担心消费者如何枚举键。
const furniture = tuple<Furniture>('chair', 'table', 'lamp')
type Furniture = 'chair' | 'table' | 'lamp' | 'ottoman';

const exhaustiveStringTuple = <T extends string>() =>
  <L extends T[]>(
    ...x: L & ([T] extends [L[number]] ? L : [
      Error, "You are missing ", Exclude<T, L[number]>])
  ) => x;

const missingFurniture = exhaustiveStringTuple<Furniture>()('chair', 'table', 'lamp');
// error, [string, string, string] is not assignable to parameter of type
// ["chair", "table", "lamp"] & [Error, "You are missing", "ottoman"]

const extraFurniture = exhaustiveStringTuple<Furniture>()(
    'chair', 'table', 'lamp', 'ottoman', 'bidet');
// error, "bidet" is not assignable to a parameter of type 'Furniture'

const furniture = exhaustiveStringTuple<Furniture>()('chair', 'table', 'lamp', 'ottoman');
// okay
const furnitureTuple = 
  <L extends Furniture[]>(
    ...x: L & ([Furniture] extends [L[number]] ? L : [
    Error, "You are missing ", Exclude<Furniture, L[number]>])
  ) => x;

const missingFurniture = furnitureTuple('chair', 'table', 'lamp');
// error, [string, string, string] is not assignable to parameter of type
// ["chair", "table", "lamp"] & [Error, "You are missing", "ottoman"]

const extraFurniture = furnitureTuple('chair', 'table', 'lamp', 'ottoman', 'bidet');
// error, "bidet" is not assignable to a parameter of type 'Furniture'

const furniture = furnitureTuple('chair', 'table', 'lamp', 'ottoman');
// okay