We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Using JS Libraries

When you're starting a new TypeScript project, you're all bright-eyed and bushy tailed, thinking to yourself, "Gee, I'm gonna have amazing type safety all throughout my project".

And then your project manager walks in and says, hey you're gonna need to npm install pregnantgoku and use that for this feature. Much to your dismay, pregnantgoku doesn't have any type definitions!

You have a couple of options:

  1. Allow the any types to flow through your code
  2. Create your own type definitions
  3. Check DefinitelyTyped and see if they have definitions for the library

DefinitelyTyped is a community-driven repository of type definitions for popular JavaScript libraries, and it's a great place to start. That said, this is a course about learning how stuff works, so let's focus on creating your own type definitions for an existing JS library. It's not hard!

You just create a new file in your project. For example, pregnantgoku.d.ts and add the following:

declare module "pregnantgoku" {
  export function kamehameha(target: [number, number]): void;
  export type Saiyan = {
    name: string;
    monthsAlong: number;
    powerLevel: number;
  };
}

Now TypeScript will use this type information when you import pregnantgoku in your code.

For internal modules, you could just export the types. For example, if you have a pregnantgoku.js file, you could write a pregnantgoku.d.ts file like this:

export function kamehameha(target: [number, number]): void;
export type Saiyan = {
  name: string;
  monthsAlong: number;
  powerLevel: number;
};

Assignment

You're importing a JavaScript module written by one of the more creative engineers at Support.ai. The runtime works fine, but TypeScript has no idea what this module exports. Time to write your own declaration.

export function log(chats) {
  for (const chat of chats) {
    console.log(`LOG: ${chat.time} | ${chat.message}`);
  }
}

export const chats = [
  {
    time: "2023-01-01T12:00:00Z",
    message: "Mom, I need the doritos",
  },
  {
    time: "2023-01-01T12:02:00Z",
    message: "MOOOOOOOOM I really need the doritos",
  },
];
import { log, chats } from "./chats.js";

// previous code

log(chats);

At this point, TypeScript should complain:

Could not find a declaration file for module './chats.js'
export type Chat = {
  // ?
};

export function log(chats: Chat[]): void;

export const chats: Chat[];

Since it's not an external module, you can just export the types. But normally you wouldn't need to create types for internal modules... hopefully.

tsc

There should be no more type errors – and autocomplete for log and chats should now work!

npx http-server .
LOG: 2023-01-01T12:00:00Z | Mom, I need the doritos
chats.js:3 LOG: 2023-01-01T12:02:00Z | MOOOOOOOOM I really need the doritos

Run and submit the CLI tests.