Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Declaring TypeScript types for design tokens that use the ES6 module format #425

Closed
johnny353535 opened this issue May 27, 2020 · 4 comments

Comments

@johnny353535
Copy link

I'm exporting my design tokens as ES6 modules and I'm having troubles figuring out a way to type these. Currently, I type them with a module.d.ts file as such:

tokens.js

export const ColorWhite = "#ffffff";
export const ColorBlack = "#222222";
...

module.d.ts

declare module 'design-tokens' {
  export const ColorWhite: string;
  export const ColorBlack:string;
  ...
}

As the tokens are generated automatically and a lot of tokens will be added in the future it's kinda tedious. I haven't seen a way to export type declarations atm and also this issue doesn't appear to cover my use case.

Has anyone had the same problem and knows a way around it?

Maybe there is a TypeScript way of declaring the module's exports dynamically? I'm thinking something like this:

declare module 'design-tokens' {
  export const [token]: string;
}
@Pegase745
Copy link

I'm handling this through a template like this

  1. Create a tempate, with this destination src/templates/typings/es6.template for example

Think of replacing the module name to reflect the real name of your module.

/**
 * Do not edit directly
 * Generated on <%= new Date().toUTCString() %>
 */

declare module 'design-tokens' {
<% _.each(allProperties, function(property) {
%>  export const <%= property.name %>: string;
<% }); %>
}
  1. Register your format in build.js
const _ = require('lodash');
const fs = require('fs');
const StyleDictionary = require('style-dictionary').extend('./config.json');

const typingsES6Template = _.template(
  fs.readFileSync(`${__dirname}/src/templates/typings/es6.template`)
);

StyleDictionary.registerFormat({
  name: 'typings/es6',
  formatter: typingsES6Template,
});

StyleDictionary.buildAllPlatforms();
  1. Use your new formatter in config.json

You can use any platform name, and destination for this

{
  "source": ["src/**/*.json"],
  "platforms": {
    "js": {
      "transformGroup": "js",
      "buildPath": "dist/",
      "files": [
        {
          "destination": "index.js",
          "format": "javascript/es6"
        }
      ]
    },
    "ts": {
      "transformGroup": "js",
      "buildPath": "dist/",
      "files": [
        {
          "destination": "index.d.ts",
          "format": "typings/es6"
        }
      ]
    },
  }
}

Result

import { ColorWhite } from 'design-tokens';  // <--- No TS errors.

Hope this helps

@monapasan
Copy link

As an alternative, you can also generate .ts files. Since typescript can infer simple types this should be enough to import constants without ts errors.

@Pegase745
Copy link

It's true, that was my first idea but I was in favor of not adding typescript deps + logic for this.

Also this method will help other developers to type the other js output such as the javascript/module for example

@voslartomas
Copy link

Hello, for those who were looking for same solution it seems there is declaration formatter included typescript/es6-declarations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants