2017-07-13 3 views
0

J'ai un problème plutôt étrange. J'étends une classe et, pour une raison quelconque, aucune des propriétés ou méthodes de la classe étendue n'est accessible. Voici ma classe:Impossible d'accéder aux propriétés de classe de base dans Typescript

import "pixi"; 
import "p2"; 
import Phaser from "phaser"; 

export class MyGameState extends Phaser.State { 
    // More stuff [...] 
    create() { 
     this.game.add.sprite(400, 300, "./assets/paddle.png"); 
    } 
} 

Cela ne fait semble compiler avec succès et exécuter, mais génère une erreur sur la façon dont il ne peut pas accéder game à this.game:

ERROR in ./src/my-game/MyGameState.ts (17,14): error TS2339: Property 'game' does not exist on type 'MyGameState'.

Intellij est aussi confus. Il semble reconnaître que create() remplace une fonction de classe de base, mais pense également que game n'existe pas.

Il est parfaitement heureux d'accéder à game au large de Phaser.State à l'intérieur de cette classe, cependant, tant que ce n'est pas la version étendue. Donc, ce compile et fonctionne très bien:

const workingState = new Phaser.State(); 
workingState.game.boot(); 

est ici une version de la classe raccourci dans phaser.d.ts J'extension:

declare module "phaser-ce" { 
    export = Phaser; 
} 

declare class Phaser { 
    class State { 
     game: Phaser.Game; 
     create(): void; 
    } 
} 

Et la configuration horriblement poilu je dois faire fonctionner la Phaser avec Tapuscrit ce puits ...

package.json

{ 
    "name": "MyGame", 
    "main": "index.js", 
    "scripts": { 
    "dev": "webpack" 
    }, 
    "devDependencies": { 
    "browser-sync": "^2.18.12", 
    "browser-sync-webpack-plugin": "^1.1.4", 
    "expose-loader": "^0.7.3", 
    "source-map-loader": "^0.2.1", 
    "ts-loader": "^2.2.2", 
    "tslint": "^5.5.0", 
    "tslint-loader": "^3.5.3", 
    "typescript": "^2.4.1", 
    "webpack": "^2.6.1" 
    }, 
    "dependencies": { 
    "phaser-ce": "^2.8.1", 
    "webfontloader": "^1.6.28" 
    } 
} 

tsconfig.json

{ 
    "compilerOptions": { 
    "outDir": "./dist/", 
    "sourceMap": true, 
    "strictNullChecks": false, 
    "module": "es6", 
    "moduleResolution": "node", 
    "target": "es5", 
    "allowJs": true 
    }, 
    "include": [ 
    "./src/" 
    ] 
} 

webpack.config.js

var path = require('path') 
var webpack = require('webpack') 
var BrowserSyncPlugin = require('browser-sync-webpack-plugin') 

// Phaser webpack config 
var phaserModule = path.join(__dirname, '/node_modules/phaser-ce/') 
var phaser = path.join(phaserModule, 'build/custom/phaser-split.js') 
var pixi = path.join(phaserModule, 'build/custom/pixi.js') 
var p2 = path.join(phaserModule, 'build/custom/p2.js') 

var definePlugin = new webpack.DefinePlugin({ 
               __DEV__: JSON.stringify(JSON.parse(process.env.BUILD_DEV || 'true')) 
              }) 

module.exports = { 
    entry: { 
     app: [ 
      path.resolve(__dirname, './src/main2.ts') 
     ], 
     vendor: ['pixi', 'p2', 'phaser', 'webfontloader'] 
    }, 
    devtool: 'source-map', 
    output: { 
     pathinfo: true, 
     path: path.resolve(__dirname, 'dist'), 
     publicPath: './dist/', 
     filename: 'bundle.js' 
    }, 
    watch: true, 
    plugins: [ 
     definePlugin, 
     new webpack.optimize.CommonsChunkPlugin(
      {name: 'vendor'/* chunkName= */, filename: 'vendor.bundle.js'/* filename= */}), 
     new BrowserSyncPlugin({ 
            host: process.env.IP || 'localhost', 
            port: process.env.PORT || 3000, 
            server: { 
             baseDir: ['./', './build'] 
            } 
           }) 
    ], 
    module: { 
     rules: [ 
      {test: /\.ts$/, enforce: 'pre', loader: 'tslint-loader', options: {emitErrors: true, failOnHint: true}}, 
      {test: /\.ts$/, loader: 'ts-loader'}, 
      {test: /pixi\.js/, use: ['expose-loader?PIXI']}, 
      {test: /phaser-split\.js$/, use: ['expose-loader?Phaser']}, 
      {test: /p2\.js/, use: ['expose-loader?p2']}, 
      {enforce: "pre", test: /\.js$/, loader: "source-map-loader"} 
     ] 
    }, 
    node: { 
     fs: 'empty', 
     net: 'empty', 
     tls: 'empty' 
    }, 
    resolve: { 
     alias: { 
      'phaser': phaser, 
      'pixi': pixi, 
      'p2': p2 
     }, 
     extensions: [".ts", ".tsx", ".js", ".jsx"] 
    } 
} 

Répondre

1

Il semble que le phaser combiné fantaisie que ma config webpack crée doit être brisé d'une manière ou d'une autre.

J'ai découvert que je pouvais éviter l'erreur dactylographiée par l'importation phaser d'une manière différente:

import * as Phaser from "phaser-ce"; 

Lors de l'importation de cette façon que je ne reçois pas d'erreurs et peut utiliser les membres de la classe de base.

1

Ce n'est pas une réponse spécifique pour Phaser, mais plus une réponse générale "où commencer".

La première étape est, consultez this:

export class MyGameState extends Phaser.State { 
    // More stuff [...] 
    create() { 
     console.log(this); 
     this.game.add.sprite(400, 300, "./assets/paddle.png"); 
    } 
} 

L'une des plus courantes gotcas dactylographiée (et JavaScript) est que this n'est pas ce que vous attendez. Cela se produit dans TypeScript lorsqu'une méthode de classe est appelée dans un contexte différent, tel qu'un événement.

Si vous trouvez que this est un élément ou un autre contexte, vous pouvez probablement résoudre le problème avec une matière grasse flèche (=>), which preserves the lexical scope.

+0

J'apprécie la suggestion. Je n'avais pas pensé à cela, mais il semble que ce n'est pas le problème. Je peux accéder à d'autres méthodes de la classe, mais pas aux méthodes de la classe de base. – CorayThan