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.
See the example code below where we have a sample user
SQL table that has columns: id
, username
, email
, password
....
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? e.g. email
being specified twice in the last line of the code sample above.
I'm after a TypeScript solution (rather than a runtime JS check).
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. 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)
However, be aware that this doesn't scale well. With 1 item in the
T
union, you get 2 tuples. With 2 items, 5 tuples. With N items, 2N + 1 tuples. The answer Fabian linked will be better for some situations, but this will provide significantly better autocomplete for others. Playground link.