简体   繁体   English

TypeScript:从字符串联合文字数组类型,不允许数组中存在任何冗余值

[英]TypeScript: from a string union literal array type, disallow any redundant values from existing in the array

I'm making use of a lot of literal string union types, and arrays of them for some code related to defining SQL tables/views, and all of their columns.我使用了很多文字字符串联合类型,其中 arrays 用于一些与定义 SQL 表/视图及其所有列相关的代码。

See the example code below where we have a sample user SQL table that has columns: id , username , email , password ....请参阅下面的示例代码,其中我们有一个示例user SQL 表,其中包含以下列: idusernameemailpassword ....

export type UserTableColumnName = 'id' | 'username' | 'email' | 'password';
export type ArrayOfUserTableColumns = UserTableColumnName[]; // This allows for redundant values, but I don't want it to allow them

function choose_some_user_table_columns(chosen_columns: ArrayOfUserTableColumns) {
    // function code not important
}

/**
 * This is fine, no error should occur:
 */
choose_some_user_table_columns(['id', 'email']);

/**
 * I want the code below to trigger a TypeScript typing error due to the 'email' element value being given twice:
 */
choose_some_user_table_columns(['id', 'email', 'email']);

Is there any way to create a type based from (or similar to) UserTableColumnName[] - but where TypeScript will trigger an error if the same value is given more than once?有什么方法可以创建基于(或类似于) UserTableColumnName[]的类型 - 但是如果多次给出相同的值,TypeScript 会触发错误吗? eg email being specified twice in the last line of the code sample above.例如email在上面代码示例的最后一行被指定了两次。

I'm after a TypeScript solution (rather than a runtime JS check).我正在寻找 TypeScript 解决方案(而不是运行时 JS 检查)。

And ideally it would also be great if my editor (vscode, or any editor that supports TypeScript) only ever suggests the column names that weren't already in the array.理想情况下,如果我的编辑器(vscode,或任何支持 TypeScript 的编辑器)只建议数组中不存在的列名,那也很棒。 As currently the intellisense will auto-suggest every column regardless of them already being in the array.目前,智能感知将自动建议每一列,无论它们是否已经在数组中。

You can do this with a mapped type representing each step in a recursive algorithm to generate all permitted array permutations.您可以使用表示递归算法中每个步骤的映射类型来执行此操作,以生成所有允许的数组排列。 (TS 4.0+ due to variadic tuple usage, you can do it in older versions, but it gets messy) (TS 4.0+ 由于可变元组的使用,你可以在旧版本中这样做,但它变得混乱)

type UniqueItems<T extends string, U extends string[] = []> = U | {
  [K in T]: UniqueItems<Exclude<T, K>, [...U, K]>
}[T]

However, be aware that this doesn't scale well.但是,请注意,这不能很好地扩展。 With 1 item in the T union, you get 2 tuples.T联合中有 1 个项目,你会得到 2 个元组。 With 2 items, 5 tuples.有 2 个项目,5 个元组。 With N items, 2 N + 1 tuples.有 N 个项目,2 N + 1 个元组。 The answer Fabian linked will be better for some situations, but this will provide significantly better autocomplete for others. Fabian 链接的答案在某些情况下会更好,但这将为其他人提供更好自动完成功能。 Playground link . 游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM