- Published on
Typescript-like Types in Python 3
- Authors
- Name
- Rohan Hussain
As a reference, you can use this site.
The need for types is strongly felt when calling functions. You need to know the exact types of the arguments of a function when calling it, otherwise the function may not work. For example, the sum function:
def sum(x, y):
return x + y
To give an integer
type to its arguments, you can use a typescript-like syntax:
def sum(x: int, y: int):
return x + y
You can also give the function's return value a type using an arrow ->
:
def sum(x: int, y: int) -> int:
return x + y
Note that Python will not throw a runtime error if one of these type checks fails.
VS Code Configuration
VS Code, by default, may not show you any error flags if you violate one of these type checks. To enable those error flags, go to VS Code settings (JSON) and set the following flag:
"python.analysis.typeCheckingMode": "basic",
Its value is usually "off"
by default.
Other Types
You can use any of the built-in types of Python, such as:
int
float
str
list
tuple
dict
: For a dictionary:def print_dictionary(my_dict: dict): for key, value in my_dict.items(): print (key, value)
Dictionaries
You can also use typing.Dict
which is more generic and lets you specify the types of the dictionary's keys and values as well. StackOverflow. However, as of Python 3.9, you should use dict
as typing.Dict
is deprecated.
Say our dictionary has string keys and integer values:
from typing import Dict
def print_dictionary(my_dict: Dict[str, int]):
for key, value in my_dict.items():
print (key, value)
As of Python 3.9, the following will also work:
def print_dictionary(my_dict: dict[str, int]):
for key, value in my_dict.items():
print (key, value)
Typed Dictionaries
What if you want to specify the exact keys that a dictionary will have? For this, we have typing.TypedDict
. Reference.
You can use TypedDict
with a class-based syntax or a functional syntax.
Class-based Syntax
To define a new dictionary type Movie
that always contains keys name
and year
:
from typing import TypedDict
class Movie(TypedDict):
name: str
year: int
def announce_movie(movie: Movie):
print("Movie",movie['name'],"was made in year", movie["year"])
announce_movie({'name': "Interstellar", 'year': 2014})
If you have configured VS Code properly, trying to access any other key on the movie
dictionary will show you a red flag. Also note that in the above type declaration, both keys name
and year
are required.
Function Syntax
from typing import TypedDict
Movie = TypedDict('Movie', {'name': str, 'year': int})
def announce_movie(movie: Movie):
print("Movie",movie['name'],"was released in year", movie["year"])
announce_movie({'name': "Interstellar", 'year': 2014})
Optional Keys
The following examples work in Python 3.9.
You can pass a third total=False
argument to the functional TypedDict()
call which makes all keys of the dictionary optional by default.
Note that if you used the old announce_movie()
function despite the optional keys, you will see a type error:
from typing import TypedDict
Movie = TypedDict('Movie',
{'name': str, 'year': int},
total=False)
def announce_movie(movie: Movie):
print("Movie",movie['name'],
"was released in year", movie["year"])
announce_movie({'name': "Interstellar"})
Your IDE would show you a type error on lines 8-9, saying that it is not guaranteed that the movie
dictionary will contain keys name
and year
.
To avoid that error:
from typing import TypedDict
Movie = TypedDict('Movie',
{'name': str, 'year': int},
total=False)
def announce_movie(movie: Movie):
if 'name' in movie:
print("Movie name is", movie['name'])
if 'year' in movie:
print("It was released in", movie["year"])
announce_movie({'name': "Interstellar"})
You could also set some keys in the dictionary as required, for example, the name
:
from typing import TypedDict
from typing_extensions import Required
Movie = TypedDict('Movie',
{'name': Required[str], 'year': int},
total=False)
def announce_movie(movie: Movie):
print("Movie", movie['name'], end='')
if 'year' in movie:
print("was released in", movie["year"])
announce_movie({'name': "Interstellar"})
This was one approach: declare all keys as optional by default and then set some as required. If the majority of the keys in your dictionary are required, then you can do the inverse. Let all keys be required by default (by removing the total=False
argument to TypedDict
), and make some optional by using typing_extensions.NotRequired
.