En tapuscrit, le type d'union est défini comme ParsedValue, qui se compose d'un type de base et d'un modèle d'interface.

Après un certain code d'analyse comme indiqué ci-dessous, le type de parsedValue est décidé en fonction du type. Maintenant, je veux faire quelque chose basé sur le type exact de parsedValue, qui est un sous-type du type union.

Cependant, j'ai trouvé que le mot-clé as ne fonctionnait pas car Template est une interface plutôt qu'une implémentation de classe.

Une solution pour contourner ce problème ?

type ParsedValue = string | number | boolean | Template | null

interface Visitor {
    visit(template: Template)
}

class BasicVisitor implements Visitor {
    visit(template: Template) {
    }
}

interface Template {
    accept(visitor: Visitor)
}

function parse(value: string, type: string): ParsedValue {
    if (type == 'template') {
        // return a template instance
    } else if (type === 'string') {
        // return some string
    } else {
        // return null
    }
}

class Field {
    type: string
    value: string
    parsedValue: ParsedValue

    constructor(json any) {
        this.value = json.value.toString()
        this.type = json.type.toString()
        this.parsedValue = parse(this.value, this.type)
    }
}

const field = new Field({
    type: 'template',
    value: 'some template string'
})

const visitor = new BasicVisitor()

if (field.parsedValue !== null && field.parsedValue as Template) {
    // how to bypass this type judgement
    field.parsedValue.accept(visitor)
}

1
Alex 17 févr. 2020 à 14:31

1 réponse

Meilleure réponse

Vous devriez essayer les protections de type définies par l'utilisateur pour les vérifications de type à l'exécution et les assertions de type : https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards

0
Markus Mauch 17 févr. 2020 à 11:45