簡體   English   中英

從包類型擴展命名空間

[英]Extend a namespace from package typings

我在這里嘗試從包類型@typings/fullcalendar擴展命名空間。

/// <reference path="./types/fullcalendar" />

import * as fullcalendar from 'fullcalendar';
import { TimeGrid } from 'fullcalendar';

// TimeGrid and fullcalendar.views are used then

原件打字可以在這里看到。

而 fullcalendar-custom.d.ts 是

import * as FC from 'fullcalendar';

export as namespace FC;

declare class TimeGrid { prepareHits() }

declare let views: any;

這會導致類型錯誤,因此很明顯fullcalendar命名空間沒有正確擴展:

TS2305:模塊 '".../node_modules/@types/fullcalendar/index"' 沒有導出成員 'TimeGrid'。

TS2339:屬性“views”在類型“typeof“.../node_modules/@types/fullcalendar/index”上不存在。

這應該如何以正確的方式完成?

考慮到types目錄是在typeRoots指定的,這里可以避免reference指令嗎?

該應用程序與 Webpack 和 awesome-typescript-loader 捆綁在一起,因此其行為可能與其他編譯方法不同。 在某些時候,IDE 檢查 (WebStorm) 中的類型似乎沒問題,但在編譯時仍然出現類型錯誤。

我們可以在非聲明.ts導入命名空間,然后將其作為擴展類型再次導出:

// custom-fc.ts : enhances declaration of FC namespace
import * as origFC from "fullcalendar";

declare namespace Complimentary {
    class TimeGrid {
        prepareHits(): void;
    }
    let views: any;
}

// apply additional types to origFc and export again
export const FC: (typeof Complimentary & typeof origFC) = origFC as any;

// use-fc.ts : consumer of extended declaration
import { FC } from "./custom-fc";

console.log(FC.TimeGrid);
console.log(FC.views);

(這在某種程度上與您的場景有所不同,因為我使用的是@types/包和 webpack ts-loader ,但您應該能夠做類似的事情。)

您可以輕松擴展“fullcalendar”或任何其他 TypeScript 命名空間。

示例:創建 fullcalendar-extension.d.ts 文件

/// <reference path="<path-to-typings-dir>/fullcalendar/index.d.ts" />

declare module 'fullcalendar' {

  export interface TimeGrid {

    customField: string;

    customMethod(arg1: number, arg2: boolean): boolean;

    prepareHits();
  }

  namespace customNamespace {

    export interface AnotherTimeGrid {
      customField1: string;
      customField2: boolean;
    }
  }
}

注意:確保這個文件被 TypeScript 編譯器選中。

使用擴展模塊中新定義的類型。

// one way
import { TimeGrid } from 'fullcalendar';

const timeGrid: TimeGrid;

// second way
import * as fc from 'fullcalendar';

const timeGrid: fc.TimeGrid;
const anotherTimeGrid: fc.customNamespace.AnotherTimeGrid;

有關模塊和命名空間的更多信息,您可以查看關於模塊命名空間的TypeScript 文檔並將它們一起使用。

干杯!

使用最新的 TypeScript v4,當我在將外部文件和庫與Svelte結合時遇到問題時,我這樣做了:

// root/my-declarations.d.ts

import { SomeNameSpace as SomeNameSpaceOriginal} from '../../any-relative-path/to/ts-file';
import {SvelteComponentDev} from 'svelte/internal';

declare namespace SomeNameSpaceExtended {
    function setValue(value:any):any
    let UI:SvelteComponentDev
    let abc:string
}

declare global {
    //this will add new items to top-level (root)
    //note: in my case, only importing "as SomeNameSpaceOriginal" gave me correct typing later using our new extended global SomeNameSpace
    let SomeNameSpace: typeof SomeNameSpaceOriginal & typeof SomeNameSpaceExtended;

    //this will add new items to window:
    interface Window {
        elementInside:'window.elementInside'
    }
}

Upvoted Answer 結合https://stackoverflow.com/a/63973683 可以讓您最了解如何擴展事物。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM