Skip to content

Type Annotation for JavaScript Objects

Derek Lewis edited this page Oct 16, 2022 · 5 revisions

TypeScript Type Annotation for JavaScript Objects

⚠︎ Anti-pattern:
Use of a banned type detected JS-0296

Description

As some standard built-in JavaScript objects are considered dangerous or harmful, some built-in types have aliases.
The practice of banning certain types is often a good idea to help improve consistency and safety.

Applies to: TypeScript
Reported by: TSLint

This rule bans specific types from being used. Does not ban the corresponding runtime objects from being used.
It takes a list of ["regex", "optional explanation here"], which bans types that match regex.

This rule includes a set of "best practices" intended to provide safety and standardization in our codebase:

  • Don't use the upper-case primitive types; lower-case types should be used for consistency:
    • Object -> object
    • Number -> number
    • String -> string
    • BigInt -> bigint
    • Symbol -> symbol
    • Boolean -> boolean

ⓧ Avoid the object type if able, as it's currently hard to use due to not being able to assert that keys exist.


⚠︎ Don't use Object as a type. Use {} instead.


⚠︎ Avoid the both Object and {} types, as they mean "any non-nullish value".
ⓘ  This is a point of confusion for many developers, who think it means "any object type".


  • Avoid the Function type, as it provides little safety for the following reasons:
    • It provides no type safety when calling the value, which means it's easy to provide the wrong arguments
    • It accepts class declarations, which will fail when called, as they are called without the new keyword

Examples

Bad Practice

// use of upper-case primitives
const str: String = "foo";
const bool: Boolean = true;
const num: Number = 1;
const symb: Symbol = Symbol("foo");

// use a proper function type
const func: Function = () => 1;

// use safer object types
const lowerObj: object = {};
const capitalObj1: Object = 1;
const capitalObj2: Object = { a: "string" };
const curly1: {} = 1;
const curly2: {} = { a: "string" };

Recommended

// use lower-case primitives for consistency
const str: string = "foo";
const bool: boolean = true;
const num: number = 1;
const symb: symbol = Symbol("foo");

// use a proper function type
const func: () => number = () => 1;

// use safer object types
const lowerObj: Record<string, unknown> = {};

const capitalObj1: number = 1;
const capitalObj2: { a: string } = { a: "string" };

const curly1: number = 1;
const curly2: Record<"a", string> = { a: "string" };
Clone this wiki locally