Typescript: typeof this.xxx donne une erreur "identificateur attendu".

Créé le 24 déc. 2014  ·  19Commentaires  ·  Source: microsoft/TypeScript

image

Est-ce par conception ou un bug?

Suggestion help wanted

Commentaire le plus utile

@ sam-s4s de nos jours, vous pouvez écrire CMultiDataset<this["thing"]> place. Les accèses indexés _do_ fonctionnent avec this (un polymorphe, même), contrairement à typeof .

Je viens d'essayer, mais cela ne fonctionne pas dans TypeScript 3.4.4, celui de @ sam-s4s fonctionne ( ClassName['thing'] ). Je pense qu'il pourrait être plus logique que this fonctionne, au lieu de pouvoir utiliser uniquement le "ClassName"?

Tous les 19 commentaires

je ne dirais ni l'un ni l'autre ... c'est juste une mauvaise syntaxe ... essayez "var copy = typeof (this.data = {});" ... ayant dit cela, je n'utiliserais pas ce code ... c'est déroutant .. .

@giancarloa hmm, vous ne devriez pas ajouter ces crochets. le code ci-dessus est juste un déclencheur de problème minimum, pas du code en production, il y aurait des situations dans lesquelles vous voudrez peut-être utiliser un code comme celui-ci.

ici, si vous prenez this à autre chose, ce serait bien et aucune erreur ne serait signalée. par exemple

class Test {
    static data = {};
    constructor() {
        var copy: typeof Test.data = {};
    }
}

Selon les spécifications

_TypeQueryExpression: _
_Identificateur_
_TypeQueryExpression_ . _IdentifierName_

C'est donc prévu.

Je pense que la raison pour laquelle ce n'est pas autorisé est que quelque chose comme ça

function foo() {
    var x: typeof this.x;
}

est parfaitement valide, car this plus ou moins a le type any . Donc, bien que cela puisse avoir du sens dans une classe, cela n'a de sens dans aucun autre contexte à moins que nous ayons # 229.

@DanielRosenwasser OO hmm ... alors en espérant que vous envisageriez de mettre à jour les spécifications. lol.

C'est quelque chose à considérer; si vos membres ne sont pas privés, vous pouvez facilement contourner ce problème avec les éléments suivants en attendant.

self = this;
var x: typeof self.data;

En attente de cette fonctionnalité.
Je pense que le cas le plus simple devrait être pris en charge
var a: typeof this.x = 1;

Et un type de membre récursif devrait conduire à une erreur.

Merci.

On dirait que cela devrait fonctionner si nous avons changé la grammaire.

@RyanCavanaugh , mais est-il approprié de l'autoriser dans le contexte que j'ai donné? Cela conduira inévitablement les gens à le faire et à obtenir any comme type.

syntaxiquement correcte ne signifie pas nécessairement que cela devrait avoir un sens, OMI.
un avertissement pourrait cependant être émis pour cette cause.

Nous vous laissons déjà écrire typeof foo.barfoo est de type any , et nous vous laissons déjà écrire this.x dans d'autres positions d'expression en pointillé lorsque le type de this est any . Je ne vois pas pourquoi leur intersection à typeof this.x devrait mériter une exception.

Juste pour ajouter un autre cas d'utilisation. Il y a quelque temps, j'ai créé les définitions de type pour lodash et certaines des signatures prises en charge sont en réalité des alias pour d'autres méthodes. Je les avais déclarés comme ceci:

interface LoDashArrayWrapper<T> {
    rest(): LoDashArrayWrapper<T>;
    rest(
        callback: ListIterator<T, boolean>,
        thisArg?: any): LoDashArrayWrapper<T>;
    rest(n: number): LoDashArrayWrapper<T>;
    rest(pluckValue: string): LoDashArrayWrapper<T>;
    rest(whereValue: {}): LoDashArrayWrapper<T>;

    drop: typeof rest;

    tail: typeof rest;
}

Cela fonctionnait bien avec la version 1.0 du compilateur. Mais il ne compile plus. Et je ne vois aucune autre option que la duplication de l'ensemble des signatures pour chaque alias car je ne peux pas penser à une TypeQueryExpression qui exprime cela.

@juanevp Et l' interface des fonctions?

interface LoDashArrayWrapper<T> {
    rest: LoDashArrayWrapperOperation<T>;
    drop: LoDashArrayWrapperOperation<T>;
    tail: LoDashArrayWrapperOperation<T>;
}

interface LoDashArrayWrapperOperation<T> {
    (): LoDashArrayWrapper<T>;
    (
        callback: ListIterator<T, boolean>,
        thisArg?: any): LoDashArrayWrapper<T>;
    (n: number): LoDashArrayWrapper<T>;
    (pluckValue: string): LoDashArrayWrapper<T>;
    (whereValue: {}): LoDashArrayWrapper<T>;
}

Approuvé. Devrait être une solution extrêmement facile? Assurez-vous que cela ne provoque pas l'émission de _this = this dans les fonctions fléchées, cependant

Est-ce lié? J'obtiens [ts] Identifier expected. avec les éléments suivants:


class UserState {
    <strong i="7">@observable</strong> state = {
        name : "",
        id : "",
    };

    <strong i="8">@action</strong>
    changeUser(user: typeof this.state) { // Error is here
        Object.assign(this.state, user);
    }
}

export const userState = new UserState();

Il serait utile de pouvoir utiliser this.state dans le cas ci-dessus.

Hmmm je viens de rencontrer ce problème :(

Je définis un objet dans ma classe.
Ensuite, je définis un autre objet qui a un paramètre de type qui doit être le type de ce qui précède.

thing = {
    a: 1,
    b: 2
};
multi: CMultiDataset<typeof this.thing>;

Dans ce cas, il n'est pas approprié de simplement changer quelque chose en une variable statique et de dire typeof ClassName.thing car ce sera différent dans chaque instance. De plus, multi doit être une variable de classe, et doit donc avoir son type dans l'heure de déclaration de classe.

@RyanCavanaugh @DanielRosenwasser @mhegazy semble être une solution relativement simple? On dirait que cela a échappé à l'attention au fil des ans ... Y a-t-il une chance qu'il soit mis en œuvre?

@ sam-s4s de nos jours, vous pouvez écrire CMultiDataset<this["thing"]> place. Les accèses indexés _do_ fonctionnent avec this (un polymorphe, même), contrairement à typeof .

Merci @weswigham - J'ai découvert que je pouvais faire CMultiDataset<ClassName['thing']> ce qui me sortait surtout des ennuis :)

Je n'ai trouvé aucune combinaison utilisant this qui fonctionnerait bien ...

@ sam-s4s de nos jours, vous pouvez écrire CMultiDataset<this["thing"]> place. Les accèses indexés _do_ fonctionnent avec this (un polymorphe, même), contrairement à typeof .

Je viens d'essayer, mais cela ne fonctionne pas dans TypeScript 3.4.4, celui de @ sam-s4s fonctionne ( ClassName['thing'] ). Je pense qu'il pourrait être plus logique que this fonctionne, au lieu de pouvoir utiliser uniquement le "ClassName"?

Si j'ai quelque chose comme
`` `dactylographié
public groupByTypes = ['None', 'Foo', 'Bar'] as const;

public groupBy: typeof groupByTypes [nombre];
`` What is the proposed workaround? And I cannot make groupByTypes` statique

Cette page vous a été utile?
0 / 5 - 0 notes