Skip to content

[postcss-preset-env] TypeScript definition files #682

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

Closed
GilShoshan94 opened this issue Nov 3, 2022 · 7 comments · Fixed by #472
Closed

[postcss-preset-env] TypeScript definition files #682

GilShoshan94 opened this issue Nov 3, 2022 · 7 comments · Fixed by #472

Comments

@GilShoshan94
Copy link

Hi,

I am very new to the world of JS/TS, HTML/CSS frontend and web in general.
Coming from system programing I feel more at home with types.

I saw the issue #600 and the response that eventually the whole plugin will be in Typescript.

I am also using PNPM, Vite, and SolidJS in Typscript.
I added the types with this pacage @types/postcss-preset-env (link to npmjs and to the repo).

Those types are not up to date, there are missing options and missing features and even deprecated features that don't exist anymore (I looked here for the options and here for the features)

So I updated locally the type definition index.d.ts:

// Type definitions for postcss-preset-env 7.7
// Project: https://github.com/csstools/postcss-plugins/tree/main/plugin-packs/postcss-preset-env
// Definitions by: Latif Sulistyo <https://github.com/latipun7>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 4.0

import { PluginCreator as PostCSSPlugin } from 'postcss';
import { Options as AutoprefixerOptions } from 'autoprefixer';

declare namespace postcssPresetEnv {
    interface pluginOptions {
        /**
         * The stage option determines which CSS features to polyfill,
         * based upon their stability in the process of becoming
         * implemented web standards.
         *
         * `postcssPresetEnv({ stage: 0 })`
         *
         * The `stage` can be `0` (experimental) through `4` (stable), or false.
         * Setting stage to false will disable every polyfill. Doing this would only
         * be useful if you intended to exclusively use the `features` option.
         *
         * Without any configuration options, PostCSS Preset Env enables
         * **Stage 2** features.
         */
        stage?: number | undefined;

        /**
         * The `minimumVendorImplementations` option determines which CSS
         * features to polyfill, based their implementation status.
         * This can be used to enable plugins that are available in browsers
         * regardless of the {@linkplain pluginOptions.stage|spec status}.
         *
         * `minimumVendorImplementations` can be `0` (no vendor has implemented
         * it) through `3` (all major vendors).
         *
         * @default 0
         */
         minimumVendorImplementations?: number | undefined;

        /**
         * The features option enables or disables specific polyfills by ID.
         * Passing true to a specific feature ID will enable its polyfill,
         * while passing false will disable it.
         *
         * Passing an object to a specific feature ID will both enable and
         * configure it.
         *
         * Any polyfills not explicitly enabled or disabled through `features`
         * are determined by the `stage` option.
         */
        features?: pluginOptions.features | undefined;

        /**
         * The browsers option determines which polyfills are required based upon
         * the browsers you are supporting.
         *
         * PostCSS Preset Env supports any standard browserslist configuration,
         * which can be a `.browserslistrc` file, a `browserslist` key in
         * `package.json`, or `browserslist` environment variables.
         *
         * The `browsers` option should only be used when a standard browserslist
         * configuration is not available.
         *
         * @default default
         */
        browsers?: string | string[] | undefined;

        /**
         * The `insertAfter` keys allow you to insert other PostCSS plugins
         * into the chain. This is only useful if you are also using sugary
         * PostCSS plugins that must execute before or after certain polyfills.
         * `insertAfter` support chaining one or multiple plugins.
         */
        insertAfter?: object | undefined;

        /**
         * The `insertBefore` keys allow you to insert other PostCSS plugins
         * into the chain. This is only useful if you are also using sugary
         * PostCSS plugins that must execute before or after certain polyfills.
         * `insertBefore` support chaining one or multiple plugins.
         */
        insertBefore?: object | undefined;

        /**
         * PostCSS Preset Env includes
         * [autoprefixer](https://github.com/postcss/autoprefixer)
         * and `browsers` option will be passed to it automatically.
         *
         * Specifying the `autoprefixer` option enables passing
         * [additional options](https://github.com/postcss/autoprefixer#options)
         * into autoprefixer.
         *
         * Passing `autoprefixer: false` disables autoprefixer.
         */
        autoprefixer?: boolean | AutoprefixerOptions | undefined;

        /**
         * The `preserve` option determines whether all plugins should receive
         * a `preserve` option, which may preserve or remove otherwise-polyfilled CSS.
         * By default, this option is not configured.
         */
        preserve?: boolean | undefined;

        /**
         * The `importFrom` option specifies sources where variables like
         * Custom Media, Custom Properties, Custom Selectors, and
         * Environment Variables can be imported from, which might be
         * CSS, JS, and JSON files, functions, and directly passed objects.
         */
        importFrom?: string | any[] | undefined;

        /**
         * The `exportTo` option specifies destinations where variables like
         * Custom Media, Custom Properties, Custom Selectors, and
         * Environment Variables can be exported to, which might be
         * CSS, JS, and JSON files, functions, and directly passed objects.
         */
        exportTo?: string | any[] | undefined;

        /**
         * The `debug` option enables debugging messages to stdout which
         * should be useful to help you debug which features have been
         * enabled/disabled and why.
         */
         debug?: boolean | undefined;

         /**
          * The `enableClientSidePolyfills` option enables any feature that
          * would need an extra browser library to be loaded into the page
          * for it to work.
          *
          * @default true
          */
         enableClientSidePolyfills?: boolean | undefined;
    }

    namespace pluginOptions {
        interface features {
            'all-property'?: boolean | object | undefined;
            'any-link-pseudo-class'?: boolean | object | undefined;
            'blank-pseudo-class'?: boolean | object | undefined;
            'break-properties'?: boolean | object | undefined;
            'cascade-layers'?: boolean | object | undefined;
            'case-insensitive-attributes'?: boolean | object | undefined;
            'clamp'?: boolean | object | undefined;
            'color-function'?: boolean | object | undefined;
            'color-functional-notation'?: boolean | object | undefined;
            'custom-media-queries'?: boolean | object | undefined;
            'custom-properties'?: boolean | object | undefined;
            'custom-selectors'?: boolean | object | undefined;
            'dir-pseudo-class'?: boolean | object | undefined;
            'display-two-values'?: boolean | object | undefined;
            'double-position-gradients'?: boolean | object | undefined;
            'environment-variables'?: boolean | object | undefined;
            'focus-visible-pseudo-class'?: boolean | object | undefined;
            'focus-within-pseudo-class'?: boolean | object | undefined;
            'font-format-keywords'?: boolean | object | undefined;
            'font-variant-property'?: boolean | object | undefined;
            'gap-properties'?: boolean | object | undefined;
            'has-pseudo-class'?: boolean | object | undefined;
            'hexadecimal-alpha-notation'?: boolean | object | undefined;
            'hwb-function'?: boolean | object | undefined;
            'ic-unit'?: boolean | object | undefined;
            'image-set-function'?: boolean | object | undefined;
            'is-pseudo-class'?: boolean | object | undefined;
            'lab-function'?: boolean | object | undefined;
            'logical-properties-and-values'?: boolean | object | undefined;
            'media-query-ranges'?: boolean | object | undefined;
            'nested-calc'?: boolean | object | undefined;
            'nesting-rules'?: boolean | object | undefined;
            'not-pseudo-class'?: boolean | object | undefined;
            'oklab-function'?: boolean | object | undefined;
            'opacity-percentage'?: boolean | object | undefined;
            'overflow-property'?: boolean | object | undefined;
            'overflow-wrap-property'?: boolean | object | undefined;
            'place-properties'?: boolean | object | undefined;
            'prefers-color-scheme-query'?: boolean | object | undefined;
            'rebeccapurple-color'?: boolean | object | undefined;
            'stepped-value-functions'?: boolean | object | undefined;
            'system-ui-font-family'?: boolean | object | undefined;
            'text-decoration-shorthand'?: boolean | object | undefined;
            'trigonometric-functions'?: boolean | object | undefined;
            'unset-value'?: boolean | object | undefined;
        }
    }

    type PostcssPresetEnv = PostCSSPlugin<pluginOptions>;
}

declare const postcssPresetEnv: postcssPresetEnv.PostcssPresetEnv;
export = postcssPresetEnv;

I saw a pull request not too old to add the new options (but didn't fix the features) but it got abbandonned, they requires tests and I am so new to this I don't feel comfortable doing it.

My question is, can those types be added directly in the postcss-preset-env package instead of being in another, unllinked, repo ? Even though it didn't get converted to typescript entirely yet.

If not, if someone know how to write tests for this and submit it to @types/postcss-preset-env (link to the repo) it would help Typescript users.

Have a nice day.


A technical/correctness question:
I modifed an existing TS file. But it seems a bit off to me.
To my understanding, in TS, ? means optional parameter wich imply that it can be undefined.
So is it correct to edit this file and remove all the | undifined on all the optional parameters ?

Another correctness question:
For all the features, the accepted type are boolean | object (and undifined because optional....).
According to the documentation, it seems that it should be only boolean. Is it the case ?

@romainmenke
Copy link
Member

Hi @GilShoshan94,

We really want to have everything typed.
Especially because it is so difficult to keep separate types correct.

To achieve this we need to do this :

  • convert each plugin in postcss-preset-env to typescript
  • have correct types for all the plugin options for all the plugins
  • convert postcss-preset-env to typescript

I do not want to spend too much time on definitely typed as I'd rather spend that time converting plugins to typescript.

This is low prio for us now because we have too many other changes planned.
But we definitely do want this.

The best way to help is to find a small and simple plugin and try converting that to typescript.

@GilShoshan94
Copy link
Author

Thank you for your reply.
I am just starting with TypeScript so I don't think I will be of any great help. All the various import systems and standards (CommonJs, EcmaScript, ESnext,...) are very confusing for newcomers...

Whish you easy translation into TypeScript.

Should I close this issue or leave it open for reference?

@romainmenke
Copy link
Member

I am just starting with TypeScript so I don't think I will be of any great help. All the various import systems and standards (CommonJs, EcmaScript, ESnext,...) are very confusing for newcomers...

I understand :)

You can leave it open as a reference.
Then we can also let you know when it is finished.

@romainmenke
Copy link
Member

🤔 Ideally plugins export the type definition of their plugin options.

@romainmenke
Copy link
Member

All needed code changes have been done for this.
It will be released as part of postcss-preset-env version 8.


Note to self :
Figure out if something needs to be done in definitely typed?
Doesn't make sense to have incorrect types there.
But I don't know how they deal with cases like this one.

@Antonio-Laguna Antonio-Laguna linked a pull request Jan 23, 2023 that will close this issue
@romainmenke
Copy link
Member

@GilShoshan94 We have released postcss-preset-env version 8 today.
With that we finally have converted everything to Typescript :

https://www.npmjs.com/package/postcss-preset-env

Screenshot 2023-01-24 at 18 29 33

@GilShoshan94
Copy link
Author

Thank you !!!

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.

2 participants