Can I force the TypeScript compiler to use nominal typing?

There is no compiler flag to make the compiler behave in a nominal way, indeed there in principle can’t be such a flag as that would break a lot of javascript scenarios.

There are several techniques generally used to emulate some kind of nominal typing. Branded types are usually used for primitives (pick one from here as a sample), for classes a common way is to add a private field (a private field will not structurally be matched by anything except that exact private field definition).

Using the last approach your initial sample could be written as:

// there is a class
class MyClassTest {
    private _useNominal: undefined; // private field to ensure nothing else is structually compatible.
    foo():void{}
    bar():void{}
}

// and a function which accepts instances of that class as a parameter
function someFunction(f:MyClassTest):void{
    if (f){
        if (!(f instanceof MyClassTest)) {
            console.log("why")
        } 
    }
}


someFunction({foo(){}, bar(){}, _useNominal: undefined})  //err

For your specific scenario, of using append I don’t think we can do anything we can do since Node is defined in lib.d.ts as an interface and a const, so augmenting it with a private field is next to impossible (without changes to lib.d.ts), and even if we could it can potentially break a lot of existing code and definitions.

Leave a Comment