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.