Advanced TypeScript: Default Type Parameters
Welcome to the Default Type Parameters lesson!
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
TypeScript generics can have default type parameters. Defaults simplify some types, especially complex types with multiple type parameters.
We'll use a small
OurArraytype as our example. It's generic, like the regularArraytype, so we can make anOurArray<string>or anOurArray<number>. But if we don't provide any type parameter at all, we want to get anOurArray<string>by default.Normally, all type parameters are required. If we don't provide them with a regular generic type, it's a type error.
>
type OurArray<T> = Array<T>;const names: OurArray = ['Amir', 'Betty'];names;Result:
type error: Generic type 'OurArray' requires 1 type argument(s).
We can declare a default type parameter with
<T=string>. It works like default function parameters, but at the type level instead of the value level. When we use the generic, any provided type parameter overrides the default. If we don't provide a parameter, we get the default ofstring.>
type OurArray<T=string> = Array<T>;const names: OurArray = ['Amir', 'Betty'];names;Result:
['Amir', 'Betty']
>
type OurArray<T=string> = Array<T>;const numbers: OurArray<number> = [10, 20];numbers;Result:
[10, 20]
>
type OurArray<T=string> = Array<T>;const numbers: OurArray = [10, 20];numbers;Result:
type error: Type 'number' is not assignable to type 'string'.
Default type parameters are relatively uncommon, but in some rare situations they're very important. One example is in component-based user interface libraries like React or Vue. React components take a "props" parameter, which is used to customize the component. For example, a button component might take
{size: 'large' | 'small'}to control the button's size.Many components need no props at all. The React type definitions accommodate those with a default type parameter.
>
type Component<Props={}> = (props: Props) => string;- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
type ButtonProps = {size: 'large' | 'small'};const Button: Component<ButtonProps> = (props) => `a ${props.size} button`;Button({size: 'large'});Result:
'a large button'
- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
const PageTitle: Component = (props) => 'Execute Program';PageTitle({});Result:
'Execute Program'
Both components use the same
Componenttype, but we can write: Componentinstead of: Component<{}>. This saves only a small amount of code in this case. But user interface code is highly repetitive, so it's nice to remove repetition wherever we can.