创建NativeScript插件时是否为index.d.ts?

时间:2019-08-28 10:49:02

标签: typescript nativescript typescript-typings

我最近开始在documention之后用NativeScript制作一个插件。我使用src文件夹中的npm run demo.ios进行了一些成功的运行。

但是,当开始构建我打算使用的实际插件时-遇到以下错误:

  

file:///node_modules/tns-core-modules/ui/builder/builder.js:179:0 JS错误错误:从XML构建UI。 @ app-root.xml:1:1   未定义不是对象(正在评估“ b.prototype”)

我已经在我试图从演示应用程序调用的ViewBase文件中的myplugin.common.ts上建立了扩展方法

我认为问题可能出在index.d.ts上。根据文档,myplugin.ios.d.tsmyplugin.android.d.ts文件应复制到此处或手动定义。我正尝试在其中复制myplugin.common.d.ts文件内容。那有效吗?

我还注意到,两次运行似乎都是不必要的-因为第一次运行会生成...d.ts.,然后必须将其中的内容复制到index.d.ts中。


一些代码...

myplugin.common.ts

declare module "tns-core-modules/ui/core/view-base/view-base" {
  interface ViewBase {
    myExenstionMethod(myNumber: number): void;
  }
}
ViewBase.prototype.myExenstionMethod = function(myNumber: number) {
  console.log("myNumber: " + myNumber);
}

index.d.ts(从myplugin.common.d.ts复制):

declare module "tns-core-modules/ui/core/view-base/view-base" {
    interface ViewBase {
        myExenstionMethod(myNumber: number): void;
    }
}

它在演示项目中显示:

enter image description here

错误来自简单地从我的演示项目中的插件中导入扩展方法:

import "nativescript-myplugin";

注意

我创建了一个新的插件项目-仅添加了扩展方法并且它起作用了。因此,原始插件项目中还有其他导致错误的原因。无需在declare module中添加index.d.ts


再次点击

具有与以前相同的错误-从myplugin.common.ts内部实例化myplugin.ios.ts / myplugin.android.ts-myplugin类时。我最初考虑要创建一个平台特定的单例实例以在.common.ts中进行交互-但这似乎行不通?

import { Gestures as iOSGestures} from "./gestures.ios";
import {Gestures as AndroidGestures} from "./gestures.android";

export abstract class Common extends Observable {
  private static _instance = null;

  static instance(os: string): Common {
    if(Common._instance == null) {
      /* crash from instantiating iOSGestures or AndroidGestures */
      this._instance = os == "iOS" ? new iOSGestures() : new AndroidGestures();
    }
    return Common._instance;
  }
  abstract _attach(viewBase: ViewBase, gesture: string): void;
}

奇怪的是,从未从任何地方调用过该特定代码。注释掉这一行,我可以通过仅包含包含实例化的无效代码来创建该错误:

// still inside .common.ts
import { Gestures } from "./gestures.android";

const object = {
  methodInFile()  {
    const g = new Gestures() // <--
  }
}

这是android.ts:

export class Gestures extends Common {
    _attach(viewBase: ViewBase, gesture: string): void {
        console.log("_attach android");
        if(gesture == touch.down) {

        }
    }
}

可能与index.d.ts有冲突?

import { Common } from './gestures.common';
export declare class Gestures extends Common {
  // define your typings manually
  // or..
  // take the ios or android .d.ts files and copy/paste them here
}

这是我第一次尝试构建插件NativeScript-因此我可能设置的东西完全错误。我希望将插件作为扩展方法提供给ViewBase-并且common.ts中定义的扩展方法会成功调用。


// inside common.ts
export class Gestures extends Common {
  _attach(): void {
      console.log("_attach ios");
  }
}
const object = {
  methodInFile()  {
    const g = new Gestures() // <--
  }
}

...有效。

但是当从另一个文件导入类时,具有new Gestures()-会导致崩溃。创建新文件-ios.common.ts均无效。因此,可能是npm run demo.ios在生成时生成了错误的js文件吗?我还完全删除了index.d.ts的内容-这样就不会引起错误。


common.ts提供一个接口-在.ios.tsandroid.ts中实现。我遇到了一个新错误;

  

file:///app/home/home-page.ts:17:27 JS错误TypeError:page.addGestureHandler不是函数。 (在'page.addGestureHandler(“ hello”)'中,'page.addGestureHandler'未定义)

到目前为止,我的结论是,我不能将Common作为抽象类或接口-将ios.tsandroid.ts实例化为单例。扩展抽象Common或实现接口Common的类必须与(common.ts)在同一文件中。 这可能与我使用扩展方法作为插件的入口点有关。

2 个答案:

答案 0 :(得分:1)

TypeScript声明temp.txt仅出于对IDE的IntelliSense支持的考虑。因此,只要导出要公开的权限定义,就没有所谓的有效或无效。大多数插件只会导出(*.d.ts),通常会暴露index.d.ts中的所有内容。

更新

为了防止生成*-common.ts.d.ts文件,您需要将.js.map中的declarationsourceMap标志设置为src/tsconfig.json。 / p>

您无法避免使用false文件,这是使用TypeScript编译器(将TS转换为JS)的唯一原因。在发布插件或在演示应用程序中使用插件时,.js文件是实际使用的文件。

之间,如果没有进行.js调试,对您来说可能会很困难。

答案 1 :(得分:0)

我终于设法以正确且令人满意的方式设置了插件

两个要点是(如果使用扩展方法作为入口点):

declare module "tns-core-modules/ui/core/view-base" {
    interface ViewBase {
        addGestureHandler(gesture: string): void;
    }
}
ViewBase.prototype.addGestureHandler = function(gesture: string) {
    console.log("addGestureHandler: " + gesture);
    // then calling platform specific singleton
}

...必须在myplugin.common.ts单独文件中定义。我称之为myplugin.ts

此设置也是如此。 myplugin.ios.tsmyplugin.android.ts必须删除。创建新文件:ios.impl.tsandroid.impl.ts。然后common.ts最终包含抽象类或接口。


因此在演示应用程序home-page.ts中,插件的用法如下:

import "nativescript-gestures"; // available only by having a common.ts file src folder in the plugin

import { NavigatedData, Page } from "tns-core-modules/ui/page";
import { HomeViewModel } from "./home-view-model";

export function onNavigatingTo(args: NavigatedData) {
    const page = <Page>args.object;
    page.bindingContext = new HomeViewModel();
    page.addGestureHandler("hello"); // <-- addGestureHandler extension method
}