bit101 / quicksettings

JavaScript library for making a quick settings panel to control code parameters.
MIT License
458 stars 52 forks source link

Add TypeScript typings #54

Closed janizde closed 4 years ago

janizde commented 4 years ago

This PR introduces TypeScript typings as a separate index.d.ts definition file within the module. Alternatively typings can be provided through https://github.com/DefinitelyTyped/DefinitelyTyped

Structure

Typing Model

By default QuickSettingsPanel is typed in a very permissive way and does not validate control names etc. when not explicitly providing a model. In this mode the typings make sure that, e.g.

Example

const permissive = QuickSettings.create(10, 10, "Foo");

permissive.setPosition('foo', 10); // Error
permissive.setPosition(10, 10); // Ok

permissive.addText('textboox', 'foo', (nextValue: string) => console.log(nextValue)); // Ok, although `textbox` contains a typo

permissive.bindText('textboox', 'foo', { textbox: 'bar' }); // Error: `textboox` does not exist on `{ textbox: string; }`

When passing QuickSettings.create<M, S> generic parameters the type checking can be made more restrictive by providing the type of a model representing the options object. This also makes sure that

Example

interface Model {
  textbox: string;
}

const restrictive = QuickSettings.create<Model>(10, 10, 'QuickSettings');

restrictive.addText('foo', 'bar'); // Error: `foo` does not exist in `Model`
restrictive.addNumber('textbox', 0, 100, 10, 1, (nextValue: number) => console.log(nextValue)); // Error: `textbox` describes a string and not a number

For controls that do not attach to the model, like buttons or elements, the second generic argument can be passed a literal type describing the keys of such controls (this is completely optional and mostly for the sake of completeness):

Example

interface Model {
  textbox: string;
}

type Buttons = 'testButton1' | 'testButton2';

const restrictive = QuickSettings.create<Model, Buttons>(10, 10, 'QuickSettings');

restrictive.addButton('testButton3', handler); // Error: `testButton3` is not in `testButton1 | testButton2`
restrictive.addButton('testButton1', handler); // OK

More examples can be found in the tests.

I'm happy to discuss the typings model and open to changes

balazsbotond commented 4 years ago

This looks like a very useful PR and I would definitely use the TypeScript typings if they were available.

janizde commented 4 years ago

@balazsbotond The types are merged into DefinitelyTyped meanwhile, since there's no progess here. https://github.com/DefinitelyTyped/DefinitelyTyped/pull/45223

You can get it as @types/quicksettings

janizde commented 4 years ago

Closing this since they're available on DefinitelyTyped now https://www.npmjs.com/package/@types/quicksettings