I want to define a type in TS where the key is dynamic, but it cannot be any old string. It must be one of the following values: 'TO_DO'
, 'IN_PROGRESS'
, or 'DONE'
.
So, for example, the data could look like this:
{columns: {
TO_DO: {
status: 'TO_DO',
title: 'To do'
taskIds: ['abc', 'def', 'ghi']
},
IN_PROGRESS: {
status: 'IN_PROGRESS',
title: 'In Progress'
taskIds: ['qrs', 'tuv', 'xyz']
}
}
This is what I did, but I don't know if it is correct:
export type Column = {
status: 'TO_DO' | 'IN_PROGRESS' | 'DONE'
title: 'To do' | 'In progress' | 'Done'
taskIds: string[]
}
export type Columns = {
[key in 'TO_DO' | 'IN_PROGRESS' | 'DONE']: Column
}
CodePudding user response:
If you're trying to make the status
match the key
, you can enforce a tighter contract using generics as follows:
export type Column<T extends string> = {
status: T
title: 'To do' | 'In progress' | 'Done'
taskIds: string[]
}
export type Columns = {
[key in 'TO_DO' | 'IN_PROGRESS' | 'DONE']: Column<key>
}
const data: Columns = {
DONE: {
status: "DONE",
taskIds: [],
title: "To do"
},
IN_PROGRESS: {
status: "DONE", // error: type '"DONE"' is not assignable to type '"IN_PROGRESS"'.
taskIds: [],
title: "To do"
}
}