我正在尝试从包类型@typings/fullcalendar
扩展命名空间。
/// <reference path="./types/fullcalendar" />
import * as fullcalendar from 'fullcalendar';
import { TimeGrid } from 'fullcalendar';
// TimeGrid and fullcalendar.views are used then
可以看到原件类型here。
并且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:类型'typeof'上不存在属性'views'... / node_modules / @ types / fullcalendar /索引“”。
如何以正确的方式做到这一点?
考虑到reference
中指定了types
目录,可以避免typeRoots
指令吗?
应用程序与Webpack和awesome-typescript-loader捆绑在一起,因此行为可能与其他编译方法不同。在某些时候,IDE检查(WebStorm)中的类型似乎没问题,但在编译时仍然存在类型错误。
答案 0 :(得分:6)
我们可以在非声明.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
,但您应该能够做类似的事情。)
答案 1 :(得分:4)
您可以轻松扩展“完整日历”&#39;或任何其他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;
有关模块和命名空间的更多信息,您可以检查Modules和Namespaces上的TypeScript文档并使用它们together。
干杯!
答案 2 :(得分:1)
使用最新的 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 相结合最能理解如何扩展事物。