typescript 从包类型扩展命名空间

xmakbtuz  于 2023-05-01  发布在  TypeScript
关注(0)|答案(4)|浏览(174)

我在这里尝试从包类型@typings/fullcalendar扩展一个名称空间。

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

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

// TimeGrid and fullcalendar.views are used then

原始打字可以看到here
全日历定制。d.ts是

import * as FC from 'fullcalendar';

export as namespace FC;

declare class TimeGrid { prepareHits() }

declare let views: any;

这会导致类型错误,所以很明显fullcalendar命名空间没有被正确扩展:
TS 2305:模块“”。../node_modules/@types/fullcalendar/index”'没有导出的成员' TimeGrid '。
TS 2339:类型“typeof”上不存在属性“views”。../node_modules/@types/ fullcalendar/index“'.
应该如何以正确的方式做到这一点?
考虑到types目录是在typeRoots中指定的,这里可以避免使用reference指令吗?
该应用程序与Webpack和awesome-typescript-loader捆绑在一起,因此其行为可能与其他编译方法不同。在某些时候,类型在IDE检查中似乎是可以的(WebStorm),但在编译时仍然会出现类型错误。

bzzcjhmw

bzzcjhmw1#

我们可以在一个非声明的.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);

(This与您的场景有所不同,因为我使用的是@types/包和webpack ts-loader,但您应该能够做类似的事情。)

x7rlezfr

x7rlezfr2#

您可以轻松扩展“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;

有关模块和命名空间的更多信息,可以查看ModulesNamespaces的TypeScript文档,并使用它们together
干杯!

5lwkijsr

5lwkijsr3#

使用最新的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相结合,提供了关于如何扩展事物的最大理解。

yuvru6vn

yuvru6vn4#

jsconfig.jsontsconfig.json添加到项目中将任何.d.ts文件添加到项目中
将代码添加到声明文件

import 'fullcalendar';

declare global {
    namespace FullCalendar {
        export * from 'fullcalendar';
    }
}

然后可以在定义的命名空间下使用此类型

相关问题