0

In TypeScript you can create a type defined by a set of particular elements:

type Context = '2d' | 'webgl' | 'webgl2'

class CanvasFacade {
  constructor(ctx: Context) {}
}

Are there any recommended ways to achieve this in Python? Presumably using libraries such as typing? Enums?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Michael Moreno
  • 947
  • 1
  • 7
  • 24
  • 3
    https://docs.python.org/3/library/typing.html#typing.Union? – jonrsharpe Oct 12 '22 at 20:20
  • @jonrsharpe So would I do `Context = Union['2d', 'webgl', 'webgl2']`, then `ctx: Context`? – Michael Moreno Oct 12 '22 at 20:27
  • That's not even valid TypeScript. – kelsny Oct 12 '22 at 20:29
  • 3
    I think you'd probably want to use `typing.Literal` here depending on what you are doing. A *union* you can do with `typing.Union` or with the `|` operator, but I guess in typescript `"2d"` is implicitly a string literal type, in Pyhton, you have to use `typing.Literal`. You *could* also use an enum if you wanted (I would generally prefer that) – juanpa.arrivillaga Oct 12 '22 at 20:33

1 Answers1

4

You're looking for typing.Union, for general unions. However, in Python, literal string types are not written as strings, so the type called '2d' in Typescript is equivalent to Literal['2d'] in Python, where Literal is also from typing.

Union[Literal['2d'], Literal['webgl'], Literal['webgl2']]

Now, if you're using Python 3.10 or newer, you can benefit from PEP 604, which allows writing union types with the bitwise-or operator.

Literal['2d'] | Literal['webgl'] | Literal['webgl2']

Finally, because this "union of literals" pattern is so common, the Literal type supports it directly.

Literal['2d', 'webgl', 'webgl2']
Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116