NativeScript:扩充tns-platform-declarations

时间:2016-11-20 09:45:54

标签: android typescript nativescript

在我的NativeScript项目中,我想要包含Android支持库中的RecyclerView。 我在app/App_Resources/Android/app.gradle中包含了依赖项:

// Uncomment to add recyclerview-v7 dependency
dependencies {
    compile 'com.android.support:recyclerview-v7:+'
}

git issue#2295和其他相关问题,我读到可以包含tns-platform-declarations来为本机android / ios库提供定义文件。 所以我安装了它们并遵循tns platform declarations documentation

我想编译以下示例代码段:

import { ContentView } from "ui/content-view";

declare var android: any;

export class OptimizedListView extends ContentView {

  private _android: android.support.v7.widget.RecyclerView;

  public _createUI() {
    this._android = new android.support.v7.widget.RecyclerView(this._context);
  }

};

如上所述声明var android会清除RecyclerView的第二个引用。但是RecyclerView的顶级参考上的以下错误仍然存​​在:

  

消息:'命名空间'android.support.v7.widget'没有导出的成员   'RecyclerView''。

我也试过声明RecyclerView类没有成功:

export declare class RecyclerView extends ContentView {}

我知道tns-platform-declarationsandroid.support.v7.widget之前有定义的事实。

“noEmitOnError”设置为false的解决方法感觉不对。

那么如何在没有编译问题的情况下将此声明扩展到android.support.v7.widget.RecyclerView

版本:

  • “nativescript-dev-typescript”:“^ 0.3.2”
  • “tns-platform-declarations”:“^ 2.4.0-2016-09-28-1”
  • “typescript”:“^ 2.1.1”
  • “tns-core-modules”:“next”

1 个答案:

答案 0 :(得分:0)

最后我根本没有使用tns-platform-declarations,因为性能非常糟糕(特别是如果你的开发机器中有< = 8GB RAM)。

我的解决方案是定义一个自己的my-typings.d.ts文件(例如在项目根目录中),我在其中定义了扩充类型RecyclerView。使用tsconfig.json默认值时,tsc会自动将其捕获。否则,可以添加exclude / includefiles个表达式。

然后你可以放置一个/// <reference path="path/to/RecyclerView/file.d.ts" />,以便Typescript编译器可以找到以下ambient global namespace

declare namespace android {

  namespace view {
    namespace ViewGroup {
      namespace LayoutParams {
        const MATCH_PARENT;
        const WRAP_CONTENT;
      }
    }
    class ViewGroup {

    }
  }

  namespace support.v7.widget {

    namespace RecyclerView {
      type AdapterImpl = {
        onCreateViewHolder(parent: android.view.ViewGroup, viewType: number): ViewHolder;
        onBindViewHolder(holder: android.support.v7.widget.RecyclerView.ViewHolder, position: number): void;
        getItemCount(): number
      };

      class Adapter {
        static extend(AdapterImpl): { new () }
      }

      class LayoutParams {
        constructor(width: any, height: any);
      }

      class ViewHolder {
        static extend: any;
      }
    }

    class RecyclerView {
      constructor(context: any);

      setAdapter(Adapter): void;
      setLayoutManager(LinearLayoutManager): void;
    }

    class LinearLayoutManager {
      constructor(context: any);
    }

  }
}

基本上,名称空间可用于模拟嵌套对象属性(例如android.view.xxx)。如果内部类是用Java定义的(Typescript似乎禁止使用嵌套的class语句),这也是这种方式。

我还必须在一些情况下定义一个与命名空间同名的类,其中我实际使用了该类型(如android.view.ViewGroup中所示)。否则你会得到以上错误

  

没有导出的成员xxx

,即使使用export显式声明类类型(并且没有必要,因为您已全局声明了命名空间)。

对于使用extend扩展本机Java类型的特殊情况,我为static extend(AdapterImpl): { new () }等相关类定义了一个静态方法,其返回类型可以用new实例化。

希望,这有助于其他类似问题。