Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restrict the intellisense/auto completion of mapped tuples depending on the first element of the tuple #43824

Open
wangdavidhao opened this issue Apr 26, 2021 · 1 comment
Labels
Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript

Comments

@wangdavidhao
Copy link

wangdavidhao commented Apr 26, 2021

Bug Report - Intellisense/Auto completion

Typescript can't infer tuple's second element type depending on first one's type

🔎 Search Terms

  • Intellisense
  • Auto completion
  • Mapped tuples

🕗 Versions

  • Typescript version v4.2.3
  • VS Code version v1.55.2

🎈 Context

The goal is to build a text editor with a structure like

Tuple = [Element, ItsAttributes, ...Tuple[]] (with mapped tuples & recursivity)

This will help when I need to construct data with this format

⏯ Payground link

Playground link

💻 Code

Creation of a type Tuple that only accepts the structure [Element, ItsAttributes] :

interface MyComponents  {
    Container: {
      fluid?: boolean
    },
    Text: {
      text?: string
      className?: string
      size: number
    }
}

//Get the keys of the list of my components
type Element = keyof MyComponents

//Create a mapped tuple type [Element, Attributes]
// and the attributes depend on the element
export type Tuple = { 

  [Element in keyof MyComponents] : readonly [Element, MyComponents[Element]]

}[keyof MyComponents]

const tuple1 : Tuple = ['Text', { size : 3}] //Okay

const tuple2 : Tuple = ['Text', { fluid : true}] //Throw error

Creation of the editor with all possibles combinations :

type RecursiveDepth = readonly [never, 0, 1, 2, 3, 4, 5, 6, 7, 8]

//Editor
type Editor<N extends number> = 
N extends 0 
? void 
: readonly [...(Tuple) , ...Editor<RecursiveDepth[N]>[]]
  | readonly [Element, ...Editor<RecursiveDepth[N]>[]]
  | readonly [...(Tuple), string]
  | readonly [...(Tuple)]
  | readonly [Element, string]
  | readonly [Element]

How to use it ?

const data : Editor<3>[] = [

  ['Container', { fluid: true}, 
    ['Text', { size : 3}]
  ]
  
]

🙁 Actual behavior

After typing first element, the second element shows all possible attributes (even the wrong ones).
When I choose a wrong one Typescript also knows it's incompatible

Example:

['Container', { /* It currently shows all attributes in MyComponents : fluid, text, className, size */}]

img3

🙂 Expected behavior

After typing first element (Container, Text, etc), Typescript shows only the attributes that belongs to it.

Example:

['Container', { /* Should only show fluid */}]  
@RyanCavanaugh RyanCavanaugh added Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript labels Apr 26, 2021
@anthonyjoeseph
Copy link

+1 This feature would help me too!

Here's a simplified example:

type tuple = ['1', '2'] | ['a', 'b']
const test: tuple = ['a', ''] //<- autocomplete on 2nd field
// actual options - 'b' | '2' ('2' will cause a type error)
// expected options - 'b'

Also it'd be great if functions had this behavior as well:

declare const func: {
  (arg1: 'a', arg2: 'b'): void
  (arg1: '1', arg2: '2'): void
}
const funcTest = func('a', '') // <- autocomplete suggests 'b' | '2'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants