Home > Software design >  In TypeScript config file 'tsconfig.json', is it redundant to set 'lib' compiler
In TypeScript config file 'tsconfig.json', is it redundant to set 'lib' compiler

Time:10-17

Based on the TypeScript documentation on the lib compiler option, is it redundant to set lib compiler option to both dom and dom.iterable in TypeScript config file tsconfig.json?

tsconfig.json

{
  "compilerOptions": {
    "lib": ["dom", "dom.iterable"],
  }
}

I personally find the above setting to be redundant, but I have seen many sample codes/blog posts using the above option. But since I'm not sure, I want to know why the above settings would be used over the following:

{
  "compilerOptions": {
    "lib": ["dom"],
  }
}

Maybe I'm just being nitpicky... Or maybe there is a valid reason unknown to me why one would specify both dom and dom.iterable. Any clarifications would be appreciated. Cheers!

CodePudding user response:

tl;dr: No, specifying both is not redundant.

dom.iterable adds definitions for iterables to various DOM APIs. You would include dom definitions if you're working with a runtime environment with DOM APIs. And you'd include dom.iterable if you are working with a runtime environment that support iterable methods on various DOM APIs. Including dom by itself when you're working with a runtime environment that support iterable methods on the DOM APIs that have them will mean you'll get type errors when attempting to access those iterable methods. Including dom.iterable by itself won't work as it adds to the dom definitions.

An example of differences

Here's an example of just one difference between the two definitions:

In the dom definitions, FormData looks like this:

interface FormData {
    append(name: string, value: string | Blob, fileName?: string): void;
    delete(name: string): void;
    get(name: string): FormDataEntryValue | null;
    getAll(name: string): FormDataEntryValue[];
    has(name: string): boolean;
    set(name: string, value: string | Blob, fileName?: string): void;
    forEach(callbackfn: (value: FormDataEntryValue, key: string, parent: FormData) => void, thisArg?: any): void;
}

reference

In the dom.iterable definitions, FormData looks like this:

interface FormData {
    [Symbol.iterator](): IterableIterator<[string, FormDataEntryValue]>;
    /**
     * Returns an array of key, value pairs for every entry in the list.
     */
    entries(): IterableIterator<[string, FormDataEntryValue]>;
    /**
     * Returns a list of keys in the list.
     */
    keys(): IterableIterator<string>;
    /**
     * Returns a list of values in the list.
     */
    values(): IterableIterator<FormDataEntryValue>;
}

reference

The definitions don't replace each other but are merged.

Below are the definition files for your own comparison:

A practical test

Knowing the differences above you can do the following test:

  1. Setup a TypeScript project with the following config (the important bit is the empty array config for lib, everything else is just the defaults from tsc --init):
{
  "compilerOptions": {
    "lib": [],

    "target": "es5",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  }
}
  1. Create an index.ts with the following contents:
const data = new FormData();

You should get an error from TypeScript:

Cannot find name 'FormData'.

  1. Add "DOM" to the lib configuration:
  "compilerOptions": {
    "lib": ["DOM"],

    ...
  }

This resolves the error as FormData is declared in the definitions for dom.

  1. Add a call to the keys method from FormData, your index.ts should look like this:
const data = new FormData();

data.keys();

You should get an error from TypeScript:

Property 'keys' does not exist on type 'FormData'.

  1. Add "DOM.Iterable" to the lib configuration:
  "compilerOptions": {
    "lib": ["DOM", "DOM.Iterable"],

    ...
  }

This resolves the error as the definitions for dom.iterable declares some iterable methods for FormData, keys being one of them.

  1. Remove "DOM" from the lib configuration, leaving just "DOM.Iterable":
  "compilerOptions": {
    "lib": ["DOM.Iterable"],

    ...
  }

You'll get an error again.

  • Related