constructorGenericCalls
Reports inconsistent placement of type arguments in constructor calls.
✅ This rule is included in the tsstylisticandstylisticStrictpresets.
When constructing a generic class, type arguments can be specified on either the left-hand side (as a type annotation) or the right-hand side (as part of the constructor call). This rule ensures that type arguments appear consistently on one side of the declaration.
Keeping to one side consistently improves code readability. The rule never reports when there are type arguments on both sides, or neither side of the declaration. It also doesn’t report if the names of the type annotation and the constructor don’t match.
Examples
Section titled “Examples”With the default "constructor" style:
const const map: Map<string, number>
map: interface Map<K, V>
Map<string, number> = new var Map: MapConstructornew () => Map<any, any> (+3 overloads)
Map();const const set: Set<string>
set: interface Set<T>
Set<string> = new var Set: SetConstructornew <string>(iterable?: Iterable<string> | null | undefined) => Set<string> (+1 overload)
Set();class class Example
Example { Example.property: Map<string, number>
property: interface Map<K, V>
Map<string, number> = new var Map: MapConstructornew () => Map<any, any> (+3 overloads)
Map();}const const map: Map<string, number>
map = new var Map: MapConstructornew <string, number>(iterable?: Iterable<readonly [string, number]> | null | undefined) => Map<string, number> (+3 overloads)
Map<string, number>();const const set: Set<string>
set = new var Set: SetConstructornew <string>(iterable?: Iterable<string> | null | undefined) => Set<string> (+1 overload)
Set<string>();const const map: Map<string, number>
map: interface Map<K, V>
Map<string, number> = new var Map: MapConstructornew <string, number>(iterable?: Iterable<readonly [string, number]> | null | undefined) => Map<string, number> (+3 overloads)
Map<string, number>();const const map: Map<any, any>
map = new var Map: MapConstructornew () => Map<any, any> (+3 overloads)
Map();class class Example
Example { Example.property: Map<string, number>
property = new var Map: MapConstructornew <string, number>(iterable?: Iterable<readonly [string, number]> | null | undefined) => Map<string, number> (+3 overloads)
Map<string, number>();}With the "type-annotation" style:
const const map: Map<string, number>
map = new var Map: MapConstructornew <string, number>(iterable?: Iterable<readonly [string, number]> | null | undefined) => Map<string, number> (+3 overloads)
Map<string, number>();const const set: Set<string>
set = new var Set: SetConstructornew <string>(iterable?: Iterable<string> | null | undefined) => Set<string> (+1 overload)
Set<string>();const const map: Map<string, number>
map: interface Map<K, V>
Map<string, number> = new var Map: MapConstructornew () => Map<any, any> (+3 overloads)
Map();const const set: Set<string>
set: interface Set<T>
Set<string> = new var Set: SetConstructornew <string>(iterable?: Iterable<string> | null | undefined) => Set<string> (+1 overload)
Set();const const map: Map<string, number>
map: interface Map<K, V>
Map<string, number> = new var Map: MapConstructornew <string, number>(iterable?: Iterable<readonly [string, number]> | null | undefined) => Map<string, number> (+3 overloads)
Map<string, number>();const const map: Map<any, any>
map = new var Map: MapConstructornew () => Map<any, any> (+3 overloads)
Map();Options
Section titled “Options”Which side should specify the type arguments:
"constructor"(default): Type arguments should be on the constructor call."type-annotation": Type arguments should be on the type annotation.
When Not To Use It
Section titled “When Not To Use It”If your codebase prefers to keep an inconsistent preference for one style over the other, you may not need this rule. Some teams prefer to use whichever style feels more natural in each context.