# check-template-names Checks that any `@template` names are actually used in the connected `@typedef`, `@callback`, `@function` or type structure. Currently checks `ClassDeclaration`, `FunctionDeclaration`, `TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as: ```ts /** * @template D * @template V */ export type Pairs = [D, V | undefined]; ``` or ```js /** * @template D * @template V * @typedef {[D, V | undefined]} Pairs */ ``` ||| |---|---| |Context|everywhere| |Tags|`@template`| |Recommended|false| |Settings|| |Options|| ## Failing examples The following patterns are considered problems: ````ts /** * @template D * @template V */ type Pairs = [X, Y | undefined]; // Message: @template D not in use /** * @template D * @template V */ export type Pairs = [X, Y | undefined]; // Message: @template D not in use /** * @template D * @template V * @typedef {[X, Y | undefined]} Pairs */ // Message: @template D not in use /** * @template D * @template V */ export type Pairs = [number, undefined]; // Message: @template D not in use /** * @template D * @template V * @typedef {[undefined]} Pairs */ // Settings: {"jsdoc":{"mode":"permissive"}} // Message: @template D not in use /** * @template D, U, V */ export type Extras = [D, U | undefined]; // Message: @template V not in use /** * @template D, U, V * @typedef {[D, U | undefined]} Extras */ // Message: @template V not in use /** * @template D * @template V * @typedef Pairs * @property {V} foo */ // Message: @template D not in use /** * @template D * @template V */ interface GenericIdentityFn { (arg: Type): Type; } // Message: @template D not in use /** * @template D * @template V */ export interface GenericIdentityFn { (arg: Type): Type; } // Message: @template D not in use /** * @template D * @template V */ export default interface GenericIdentityFn { (arg: Type): Type; } // Message: @template D not in use /** * @template D * @template V */ function identity(arg: Type): Type { return arg; } // Message: @template D not in use /** * @template D * @template V */ export function identity(arg: Type): Type { return arg; } // Message: @template D not in use /** * @template D * @template V */ export default function identity(arg: Type): Type { return arg; } // Message: @template D not in use /** * @template D * @template V */ class GenericNumber { zeroValue: NumType; add: (x: NumType, y: NumType) => NumType; } // Message: @template D not in use /** * @template D * @template V */ export class GenericNumber { zeroValue: NumType; add: (x: NumType, y: NumType) => NumType; } // Message: @template D not in use /** * @template D * @template V */ export default class GenericNumber { zeroValue: NumType; add: (x: NumType, y: NumType) => NumType; } // Message: @template D not in use /** * @template D * @template V */ export default class { zeroValue: NumType; add: (x: NumType, y: NumType) => NumType; } // Message: @template D not in use /** * @template D * @template V * @callback * @returns {[X, Y | undefined]} */ // Message: @template D not in use /** * @template D * @template V * @function * @returns {[X, Y | undefined]} */ // Message: @template D not in use /** * @template D * @template V * @function * @param {[X, Y | undefined]} someParam */ // Message: @template D not in use /** * @template */ // Settings: {"jsdoc":{"tagNamePreference":{"template":false}}} // Message: Unexpected tag `@template` ```` ## Passing examples The following patterns are not considered problems: ````ts /** * @template D * @template V */ export type Pairs = [D, V | undefined]; /** * @template D * @template V * @typedef {[D, V | undefined]} Pairs */ /** * @template D, U, V */ export type Extras = [D, U, V | undefined]; /** * @template D, U, V * @typedef {[D, U, V | undefined]} Extras */ /** * @template X * @typedef {[D, U, V | undefined]} Extras * @typedef {[D, U, V | undefined]} Extras */ /** * @typedef Foo * @prop {string} bar */ /** * @template D * @template V * @typedef Pairs * @property {D} foo * @property {V} bar */ /** * @template Type */ interface GenericIdentityFn { (arg: Type): Type; } /** * @template Type */ export interface GenericIdentityFn { (arg: Type): Type; } /** * @template Type */ export default interface GenericIdentityFn { (arg: Type): Type; } /** * @template Type */ function identity(arg: Type): Type { return arg; } /** * @template Type */ export function identity(arg: Type): Type { return arg; } /** * @template Type */ export default function identity(arg: Type): Type { return arg; } /** * @template NumType */ class GenericNumber { zeroValue: NumType; add: (x: NumType, y: NumType) => NumType; } /** * @template NumType */ export class GenericNumber { zeroValue: NumType; add: (x: NumType, y: NumType) => NumType; } /** * @template NumType */ export default class GenericNumber { zeroValue: NumType; add: (x: NumType, y: NumType) => NumType; } /** * @template NumType */ export default class { zeroValue: NumType; add: (x: NumType, y: NumType) => NumType; } /** * Uses the provided callback to group the given array into the keys of a map. * Based on the array grouping proposal: https://github.com/tc39/proposal-array-grouping/ * * @template T * @param {T[]} array * @param {(value: T, index: number) => string} callbackFn * @returns {Map} */ export function mapGroupBy(array, callbackFn) { } /** * @template D * @template V * @callback * @returns {[D, V | undefined]} */ /** * @template D * @template V * @function * @returns {[D, V | undefined]} */ /** * @template D * @template V * @function * @param {[D, V | undefined]} someParam */ /** * @template {string} U */ export class User { /** * @type {U} */ name; } /** * @template {string} U */ export class User { /** * @param {U} name */ constructor(name) { this.name = name; } methodToIgnore() {} } /** * @template [ChannelDataType=undefined] * @param {string} messageType - A key used for sending and receiving messages. * @returns {MessageChannel} A channel that can create messages of its * own type. */ export function createMessageChannel(messageType) { // Note: It should also infer the type if the new channel is returned // directly rather than returned as a typed variable. /** @type {MessageChannel} */ const messageChannel = new MessageChannel(messageType); return messageChannel; } /** * @template T * @augments {Set} */ export class MySet extends Set {} /** * @template U * @extends {Set} */ export class MySet extends Set {} /** * @template T * @implements {Iterable} */ export class MyIterable {} ````