How to overwrite incorrect TypeScript type definition installed via @types/package

后端 未结 4 793
悲哀的现实
悲哀的现实 2020-12-02 08:28

Say that I want to use dotenv module in my TypeScript project and install its .d.ts using npm install @types/dotenv --save. Then I realize that the

相关标签:
4条回答
  • 2020-12-02 08:59

    I would copy the declaration files from DefinitelyTyped, modify them locally, send a PR to DefinitelyTyped, and then follow the advice given on the following question to use the changes immediately: How can I write and use custom declaration files that don't exist on DefinitelyTyped?

    Sending updates to DefinitelyTyped

    1. Head over to the DefinitelyTyped repo: https://github.com/DefinitelyTyped/DefinitelyTyped/
    2. Clone your fork locally. (often just git clone https://github.com/YourUserName/DefinitelyTyped/)
    3. Create a branch for your updates (e.g. git branch changes-to-xyz)
    4. Make changes to the package you're interested in.
    5. Add and commit files. (git add types; git commit)
    6. Then push them to your fork of DefinitelyTyped (git push -u origin changes-to-xyz)

    Using those updates locally

    1. Create a local-types folder in your project.
    2. Copy the DefinitelyTyped folder (let's call it xyz) you modified and into local-types/xyz.
    3. From local-types/xyz, run npm init --scope types --yes.
    4. From the root of your project, run npm install local-types/xyz

    That's it!

    0 讨论(0)
  • 2020-12-02 09:06

    A way that is not mentioned here is to put a type declaration in a index.d.ts file. For my case, the types from @types/react-bootstrap were not correct.

    I wanted to use bsClass as declared in the documentation, but it did not exist in Popover. Instead they included a prop that does not exist on Popover namely bsStyle.

    The fix for me was to remove bsStyle and add bsClass:

    import * as React from "react";
    import { Sizes } from "react-bootstrap";
    
    // Overwrite bad declaration from @types/react-bootstrap
    declare module "react-bootstrap" {
        namespace Popover {
            export interface PopoverProps extends React.HTMLProps<Popover> {
                // Optional
                arrowOffsetLeft?: number | string;
                arrowOffsetTop?: number | string;
                bsSize?: Sizes;
                bsClass?: string; // This is not included in types from @types/react-bootstrap
                placement?: string;
                positionLeft?: number | string;
                positionTop?: number | string;
            }
        }
        class Popover extends React.Component<Popover.PopoverProps> { }
    }
    

    Update

    I finally bit the bullet and uploaded a PR to DefinitelyTyped for adding a few missing bsClass / bsSize declarations.

    Update 2: An example using declaration merging

    I wanted the img loading="lazy" attribute for the <img> tag in React, but it's not merged yet. I solved it this way:

    File: global.d.ts

    // Unused import - only used to make this file a module (otherwise declare global won't work)
    // tslint:disable-next-line:no-unused
    import React from "react";
    
    // Extend HTMLImageElement to support image lazy loading
    // https://addyosmani.com/blog/lazy-loading/
    declare global {
        namespace React {
            interface ImgHTMLAttributes<T> {
                loading?: "lazy" | "eager" | "auto";
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-02 09:07

    I would check that the version of dotenv and the version of @types/dotenv are aligned, that may be the cause of the function missing.

    If they are then the cleaner way would be to modify the .d.ts yourself.

    In order to do this: npm remove @types/dotenv. Create a folder types on your project. Copy the whole folder dotenv found in node_modules/@types into it.

    Then fix your d.ts in it and modify your tsconfig.json to tell it to also look in your new folder for missing types with typeRoots like this:

    {
    "compilerOptions": {
        "module": "commonjs",
        "noImplicitAny": true,
        "typeRoots": [
            "./node_modules/@types",
            "./types/",
        ]
    },
    "files": ["./app.ts"]
    }
    

    (Don't forget to add ./node_modules/@types or other types you got with npm that won't be found anymore.)

    Hope it helps!

    0 讨论(0)
  • 2020-12-02 09:07

    You can patch @types/foo locally for your app by patch-package.

    1. Run npm i -D patch-package

    2. Simply modify node_modules/@types/foo to suit your needs.

    3. Run npx patch-package @types/foo. This creates a diff file in patches/ that records the changes made from the last step.

    4. Add scripts: {postinstall: "patch-package"} in package.json. This make patches to be applied each time people run npm install.

    0 讨论(0)
提交回复
热议问题