# @rushstack/typings-generator

## Installation

`npm install @rushstack/typings-generator --save-dev`

## Overview

This is a utility for generating typings for non-TS files. It can operate in either a single-run mode or
a watch mode. It is designed to generate `.d.ts` files with a specified generation function for all files matching
specified file extensions, with an option to ignore individual files.

## Usage

```TypeScript
import { TypingsGenerator } from '@rushstack/typings-generator';

const typingsGenerator: TypingsGenerator = new TypingsGenerator({
  srcFolder: '/repo/package/src',
  generatedTsFolder: '/repo/package/temp/generated-typings',
  fileExtensions: ['file-extension'],
  parseAndGenerateTypings: (fileContents: string, filePath: string) => {
    const parsedFile = parseFile(fileContents);
    const typings: string = generateTypings(parsedFile);
    return typings;
  }
});

// To run once before a compilation:
await typingsGenerator.generateTypings();

// To start a watcher:
await typingsGenerator.runWatcher();
```

```TypeScript
import { TypingsGenerator } from '@rushstack/typings-generator';

const assetTypingsGenerator: TypingsGenerator = new TypingsGenerator({
  srcFolder: '/repo/package/src',
  generatedTsFolder: '/repo/package/temp/generated-typings',
  fileExtensions: ['.jpg'],
  parseAndGenerateTypings: (fileContents: false, filePath: string) => {
    const parsedFile = parseFile(fileContents);
    const typings: string = 'declare const path: string;\nexport default path;';
    return typings;
  },
  // Don't read files at all
  readFile: (filePath: string, relativePath: string) => false
});

// To run once before a compilation:
await typingsGenerator.generateTypings();

// To start a watcher:
await typingsGenerator.runWatcher();
```

## Options

### `srcFolder = '...'`

This property is used as the source root folder for discovery of files for which typings should be generated.

### `generatedTsFolder = '...'`

This property specifies the folder in which `.d.ts` files should be dropped. It is recommended
that this be a folder parallel to the source folder, specified in addition to the source folder in the
[`rootDirs` `tsconfig.json` option](https://www.typescriptlang.org/docs/handbook/compiler-options.html).
**The folder specified by this option is emptied when the utility is invoked.**

### `fileExtensions = [...]`

This property enumerates the file extensions that should be handled.

### `parseAndGenerateTypings = (fileContents: TFileContents, filePath: string, relativePath: string) => string | Promise<string>`

This property is used to specify the function that should be called on every file for which typings
are being generated. In watch mode, this is called on every file creation and file update. It should
return TypeScript declarations for the file it is called with.

### `readFile = (filePath: string, relativePath: string) => TFileContents | Promise<TFileContents>`

This property allows customizing the process by which files are read from the specified paths.
Use cases include:
- Disabling reads altogether, if the typings don't depend on file content
- Reading from an alternate data source
- Reading files with a different encoding than 'utf-8'

### `terminal`

Optionally provide a [Terminal](https://github.com/microsoft/rushstack/blob/main/libraries/terminal/src/Terminal.ts)
object for logging. If one isn't provided, logs will go to the console.

### `globsToIgnore`

Optionally, provide an array of globs matching files that should be ignored. These globs are evaluated
under [`srcFolder`](#srcFolder--)

## `StringValuesTypingsGenerator`

There is an extension of this utility specifically for file types where typings should be a simple
set of exported string values. This is useful for file types like CSS and RESX. This class takes
the same options as the standard `TypingsGenerator`, with one additional option ([`exportAsDefault`](#exportAsDefault--)) and a different return value for `parseAndGenerateTypings`.

### `parseAndGenerateTypings = (fileContents: string, filePath: string) => { typings: ({ exportName: string, comment?: string })[] } | Promise<{ typings: ({ exportName: string, comment?: string })[] }>`

This function should behave the same as the `parseAndGenerateTypings` function for the standard
`TypingsGenerator`, except that it should return an object with a `typings` property, set to
an array of objects with an `exportName` property and an optional `comment` property.
See the example below.

#### Example return value:

```TypeScript
{
  typings: [
    {
      exportName: 'myExport'
    },
    {
      exportName: 'myOtherExport',
      comment: 'This is the other export'
    }
  ]
}
```

#### Example generated declaration file:

```TypeScript
// This file was generated by a tool. Modifying it will produce unexpected behavior

export declare const myExport: string;

/**
 * This is the other export
 */
export declare const myOtherExport: string;

```

### `exportAsDefault = true | false`

If this option is set to `true`, the typings will be exported wrapped in a `default` property. This
allows the file to be imported by using the `import myFile from './myFile.my-extension';` syntax instead of
the `import { myExport } from './myFile.my-extension';` or the `import * as myFile from './myFile.my-extension';`
syntax. This style of export is not recommended as it can prevent tree-shaking optimization.

### `exportAsDefaultInterfaceName = true | false`

When `exportAsDefault` is true, this optional setting determines the interface name
for the default wrapped export. For example, in the Sass Typings plugin, the interface name
is set to `IExportStyles`. If not specified, the interface name will be `IExport`.
(This setting is ignored when `exportAsDefault` is false).

## Links

- [CHANGELOG.md](https://github.com/microsoft/rushstack/blob/main/libraries/typings-generator/CHANGELOG.md) - Find
  out what's new in the latest version
- [API Reference](https://api.rushstack.io/pages/typings-generator/)

`@rushstack/typings-generator` is part of the [Rush Stack](https://rushstack.io/) family of projects.
