1

我正在尝试使用 angular2 在电子中制作一个小程序,它运行良好,直到我尝试在数组上使用 find 函数。在那里,我得到了一个错误

Property 'find' does not exist on type 'MyType[]'.

作为新手,看不懂报错,于是稍微搜索了一下,发现electron使用的js引擎能理解ES5,而不是ES6.

这就是为什么 sees6-shim在 angular2 中使用库填充的原因。但是,如果是这样,我不应该得到这个错误,不是吗?

我的 tsconfig.js 文件是这样的:

{
    "compilerOptions": {
        "target": "ES5",
        "module": "commonjs",
        "moduleResolution": "node",
        "removeComments": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "sourceMap": true,
        "noImplicitAny": false
    },
    "exclude": [
        "node_modules",
        "typings/index",
        "typings/index.d.ts"
    ],
    "compileOnSave": false,
    "buildOnSave": false
}

我也使用 ,webpack配置如下:

var path = require('path');
var webpack = require('webpack');
var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;

module.exports = {
    devtool: 'source-map',
    debug: true,

    entry: {
        'angular2': [
            'rxjs',
            'reflect-metadata',
            'angular2/core',
            'angular2/router',
            'angular2/http'
        ],
        'app': './app/app',
        'vendor': [
            'es6-shim',
            'es6-shim/es6-sham'
        ]
    },

    output: {
        path: __dirname + '/build/',
        publicPath: 'build/',
        filename: '[name].js',
        sourceMapFilename: '[name].js.map',
        chunkFilename: '[id].chunk.js'
    },

    resolve: {
        extensions: ['', '.ts', '.js', '.json', '.css', '.html']
    },

    module: {
        loaders: [{
            test: /\.ts$/,
            loader: 'ts',
            exclude: [/node_modules/]
        }]
    },

    plugins: [
        new CommonsChunkPlugin({
            name: 'angular2',
            filename: 'angular2.js',
            minChunks: Infinity
        }),
        new CommonsChunkPlugin({
            name: 'common',
            filename: 'common.js'
        }),
        new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js')
    ]
};

我想,我的项目中存在配置错误。但我找不到它。

先感谢您。

更新 1

以下是package.json文件的内容:

{
    "name": "videos-for-kids",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "author": "Charalampos Chrysikopoulos",
    "license": "ISC",
    "scripts": {
        "build": "webpack --progress --profile --colors --display-error-details --display-cached",
        "watch": "webpack --watch --progress --profile --colors --display-error-details --display-cached",
        "start": "electron ."
    },
    "devDependencies": {
        "awesome-typescript-loader": "^0.15.10",
        "electron-prebuilt": "^1.2.6",
        "electron-reload": "^1.0.0",
        "ts-loader": "^0.7.2",
        "typescript": "^1.8.10",
        "webpack": "^1.12.9",
        "webpack-dev-server": "^1.14.0",
        "typings": "^1.3.1",
        "tslint": "^3.7.4",
        "ts-helpers": "^1.1.1",
        "imports-loader": "^0.6.5",
        "json-loader": "^0.5.4"
    },
    "dependencies": {
        "angular2": "2.0.0-beta.17",
        "systemjs": "0.19.26",
        "es6-shim": "^0.35.1",
        "reflect-metadata": "0.1.2",
        "rxjs": "^5.0.0-beta.6",
        "zone.js": "^0.6.12",
        "bootstrap": "^3.3.6"
    }
}

更新 2

这也是有错误的类:

import { Injectable } from 'angular2/core';
import { Http, Response } from 'angular2/http';
import { Observable } from 'rxjs/Observable';

import 'rxjs';

import {IVideo} from '../model/IVideo';

@Injectable()
export class VideoService {

    private _serviceUrl = 'file://pathTo/app/data/videos.json';

    constructor(private _http: Http) { }

    public getVideos(): Observable<IVideo[]> {
        return this._http.get(this._serviceUrl)
        .map((response: Response) => <IVideo[]> response.json())
        .catch(this.handleError);
    }

    private handleError(error: Response) {
        return Observable.throw(error.json().error || 'Server error');
    }

    getVideo(id: number): Observable<IVideo> {
       return this.getVideos()
            .map((videos: IVideo[]) => videos.find(v => v.id === id));
    }

}
4

1 回答 1

2

更新 所以你给了我一个我忽略的线索,这让我陷入了一个需要一点时间才能摆脱的兔子洞。我什至建立了一个plunker,向自己证明你试图做的事情是有效的(尽管很明显你正在做的事情会奏效)。果然,我能够毫无问题地使用 Array.prototype.find() 方法。

//excerpt from plunker src/video.service.ts
getVideo(id: number): Observable<IVideo> {
   return this.getVideos()
        .map((videos: IVideo[]) => videos.find(v => v.id === id));
}

plunker 和 VS Code 之间的区别在于,在 plunker SystemJS 实际上是执行 TypeScript 转译,其中 VS Code 使用TypeScript编译器本身执行转译。

但是,您在评论中指出,在执行转译时您没有收到此错误。在您尝试转译 .ts 代码之前,您会在 VS Code“问题”窗口中看到此错误。

我觉得这很奇怪,所以我回到了基础。我创建了一个新的 VS Code 项目,并创建了一个简单的界面并实例化了一个数组。然后我尝试在该数组上执行 .find() 。VS Code 立即在问题窗口中通知我此方法不存在。VS Code Problem 窗口没有使用 TypeScript 来识别问题。

VS Code 实际上使用了另一个名为Typings的包,typings 允许 VS Code 扩展它自己的解析代码和提供智能感知的能力。您的 package.json(devDependencies) 文件和 tsconfig.json(exclude section) 文件中已经有提示,您也有 Typings。

这意味着您已安装工具,但未配置项目。我敢打赌,如果您查看“typings.json”文件,您应该会看到“es6-shim”的条目。您应该会看到类似这样的内容(如果这不存在,请在您的根目录中创建文件并将其放入其中)。

{
"globalDependencies": {
    "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#7de6c3dd94feaeb21f20054b9f30d5dabc5efabd"
    }
}

为了让 VS Code 使用“es6-shim”,它需要被安装。Typings 包已经安装,但类型本身还没有安装在项目中。要在工具栏上的 VS Code 中执行此操作,请选择“查看 -> 集成终端”(ctrl + `)。您将看到一个命令提示符。如果您在全局范围内安装了 Typings,则可以输入此命令。

typings install

否则(它在本地安装)

node_modules\.bin\typings install

如果其中任何一个给你一个错误,那么 Typings 就没有安装,你需要确保你的 package.json 仍然有依赖“typings”。如果确实如此,则执行“npm install”,然后重复上述步骤。

之后,重新启动 VS Code,错误应该不再存在!

此外,您应该将 tsconfig.json 文件的“排除”部分更新为

"exclude": [
    "node_modules",
    "typings/globals",//<----------
    "typings/index.d.ts"
]

什么时候出现这个错误?是在编译时还是在运行 Electron 应用程序时?另外,您使用的是什么版本的 TypeScript?您使用的是哪个版本的 Angular2 测试版?你的“package.json”文件会告诉你这些事情。

如果这发生在编译时,则意味着 TypeScript 不知道数组的“查找”方法,这很奇怪。TypeScript 不知道你的 webpack 的东西,所以升级你的 TypeScript 版本可能会做到(我正在运行 '1.8.10' 并且它识别 'find' 方法)。

如果这发生在 Electron 运行内部,可能是几件事。

可能是 webpack 没有加载 shim,您应该能够通过打开开发人员工具并查看 Network 选项卡下查看是否看到对 shim 的请求来查看是否属实。如果你没有看到它,那么你就知道这是一个 webpack 问题。

可能是 es6-shim 缺少其中的“查找”方法。最好使用替代shim,在您想要使用 /client/shim.min.js 文件的链接中。

它可能是您使用的角 beta 版本没有在 es6-shim 中定义。这很奇怪,但是您可以自己升级最新版本的Angular2,在示例中他们使用 SystemJS 调用引导程序,因此您可能需要将其转换为 webpack。我在没有垫片的情况下运行@angular 版本'2.0.0-rc.4',我可以在运行时使用'find'方法。

还认为它可能是您正在运行的 Electron 版本(因为我不需要 shim),我正在运行这个版本的 Electron。

于 2016-07-17T14:36:50.607 回答