I am very new in Typescript and I have an issue which I don't know how to resolve it :(.
Basically I want to create a list of tuple from a list of components. The first element of the tuple is the element's name (keyof MyComponents) and the second elements is its attributes.
(See code below)
interface MyComponents {
Container: {
fluid?: boolean
className?: string
},
Tag: {
text?: string
className?: string
hidden: boolean
}
}
//Get the keys of the list of my components
type Element = keyof MyComponents
//Get the attributes depending on the element name
type PickAttributes<T extends Element> = Pick<MyComponents[T], keyof MyComponents[T]>
//Create a mapped tuple type [Element, Attributes]
// and the attributes depend on the element
export type Tuple = {
[Element in keyof MyComponents] : [Element, PickAttributes<Element>]
}[keyof MyComponents]
const attr : PickAttributes<'Tag'> = {hidden : false} //This works and the auto completion works perfectly
const tuple1 : Tuple = ["Tag", { hidden: false}] //This also works
const tuple2 : Tuple = ["Container", { hidden: false}] //Error but it's normal as the element 'Container' doesn't have the property hidden:boolean
Everything works perfectly but there is a small problem for autocompletion. When I type the first element (Container, Tag, ...), the auto completion of the second element (its attributes) shows all the possible attributes even the wrong ones.
As an example if I type 'Tag' for the first element it suggets me 'fluid' but 'fluid' is only available in 'Container' ! Intellisense shows all options
And when I choose fluid, it also knows it's incompatible...
Typescript knows it's incompatible
So my question is: How can I restrict the autocomplete to only shows valid attributes depending on the element's name ?
Any help will be appreciated ! Thanks !**
I can't speak to your title question as to why intellisense does that, but I can give you two options to answer the question "How can I restrict the autocomplete to only shows valid attributes depending on the element's name?":
Option 1, Use objects instead of arrays to model the tuple:
Option 2, use a tuple constructor function:
playground