my-awesome-typescript-project / src/generic-types
Generic types.
Defined in: src/generic-types.ts:28
Generic interface
- Defines public contracts (no need to define constructor).
- Read the notes for best practices on accessors.
| Type Parameter |
|---|
T |
setOne(one): void;Defined in: src/generic-types.ts:29
| Parameter | Type |
|---|---|
one |
T |
void
getOne(): T;Defined in: src/generic-types.ts:30
T
Defined in: src/generic-types.ts:42
Generic class
- Can be made more adaptable if T is an object shape instead of a primitive type.
- Use indexed types to access object shape inner types and type private properties.
- Class expressions are a pain when made generic because of tsconfig's
isolatedDeclarations, avoid.
| Type Parameter |
|---|
T |
new genericClass<T>(one): genericClass<T>;Defined in: src/generic-types.ts:44
| Parameter | Type |
|---|---|
one |
T |
genericClass<T>
setOne(one): void;Defined in: src/generic-types.ts:45
| Parameter | Type |
|---|---|
one |
T |
void
getOne(): T;Defined in: src/generic-types.ts:46
T
const e: InstanceType<typeof genericClass>;Defined in: src/generic-types.ts:56
Generic class usage
- Removing the type annotation on the constructor call makes the compiler infer the type from the argument, avoid.
- Utility types are useful for annotating exports of generic-based classes instances.
type genericFn<T, U> = (a, b) => [U, T];Defined in: src/generic-types.ts:77
Generic function type expression
| Type Parameter |
|---|
T |
U |
| Parameter | Type |
|---|---|
a |
T |
b |
U |
[U, T]
- Declare a (simple here) function signature over 2 generic types.
- Returned value must be a tuple of types (subtype of the array).
- Best practices :
- Always use as few type parameters as possible.
- When possible, use the type parameter itself rather than constraining it.
- If a type parameter only appears in one location, strongly reconsider if you actually need it.
- The same result can be achieved with interfaces, however types are preferred.
- Note : it is not possible to create generic enums and namespaces.
const generic: genericFn<string, number>;Defined in: src/generic-types.ts:87
Function implementation using a generic
- Always separate signature declaration and function implementation (for clarity).
- Typescript can also infer types from generic functions arguments.
- However, it is better to always provide functions implementations with specific types as seen below.
type constrainedFn<T> = (o) => string;Defined in: src/generic-types.ts:116
Constrained generic types
| Type Parameter |
|---|
T extends objectShape |
| Parameter | Type |
|---|---|
o |
T |
string
- Equivalent of
type constrainedFn<T> = T extends objectShape ? (o: T)=> string : never;, which one is better is debatable.
const constrained: constrainedFn<
| objectShape
| extendedShape>;Defined in: src/generic-types.ts:125
Constrained function implementation and typing.
- Type inference is possible in this case as well but also discouraged.
- Also see this very important consideration on constraints.
Defined in: src/generic-types.ts:144
Constrained generic class.
- Extending a generic interface to isolate declaration makes no point in this case.
- Note : _ static class members cannot use the type parameters_.
- See also this guide on how to set defaults for type parameters.
- This example also illustrates the use of indexed access types.
| Type Parameter |
|---|
T extends |
new constrainedGenericClass<T>(z): constrainedGenericClass<T>;Defined in: src/generic-types.ts:147
| Parameter | Type |
|---|---|
z |
T |
| Property | Type | Defined in |
|---|---|---|
six |
T |
src/generic-types.ts:145 |
seven |
T["three"] |
src/generic-types.ts:146 |
eight(): number;Defined in: src/generic-types.ts:152
number
type callableProps = "three" | "four";Defined in: src/generic-types.ts:163
Union of callable object properties.
keyofdoesn't work here, keys must be declared using a dedicated union type.
type makeCallable<T, R> = (this, ...s) => ReturnType<T[R]>;Defined in: src/generic-types.ts:171
Generic callable object type.
| Type Parameter |
|---|
T extends objectShape |
R extends callableProps |
| Parameter | Type |
|---|---|
this |
T |
...s |
Parameters<T[R]> |
ReturnType<T[R]>
- From there, any object that matches the generic type can be made callable.
type callableLiteral = objectShape & makeCallable<objectShape, "three">;Defined in: src/generic-types.ts:181
Type an existing object shape as callable.
- Use the generic to bind the object call signature to on if its methods.
const callThisLiteral: callableLiteral;Defined in: src/generic-types.ts:189
Implement a typed callable object literal.
- Declare literal as a function then add missing keys, compiler OK.