Typing check for Typedef

I read @nadako abstract blog post and in Use case: object identifiers he note that their is no type checking for typedef(I.e MyTypedef ->Int->Void function can accept simple int for MyTypedef argument), why?
Example: Try Haxe !

Typedefs don’t remove type checking, it’s just that they aren’t a new type, only a named alias.

typedef A = Int;
typedef B = Int;

function main () {
    var a : A = 5;
    var b : B = 6;
    test(a);
    test(b);
    test(12);
}
function test (i:Int) {}

This compiles because it says that var a and b are of type Int, here called through a “nickname” but still Int.

Abstracts are different, they are a new type and therefor don’t unify Unification - Haxe - The Cross-platform Toolkit unless they have to/from functions to do so Implicit Casts - Haxe - The Cross-platform Toolkit.

1 Like

I understand that, but if I decided to let test function get MyTypedef argument, so this is should be only MyTypedef, this is probably should not match as regular Int, you can give me example of function that get MyTypedef but you also might want to pass it a regular Int?
I’m not sure but maybe if typedef include this kind of typedef things will get messy with objects? i.e:

function test(obj:{a:String, b:Int}) {}
typedef MyTypedef = {a:String, b:Int}

public function new () {
  var obj:MyTypedef = {a:"test", b:1};
  test(obj); // OK
  test({a:"test", b:1}); // Will cause error
}

The thing is that MyTypedef isn’t exactly a type, it’s a type alias. You’re not saying that the test function takes a MyTypedef argument but an Int, you’re just using an alternate name for it.
(that’s a bit of an oversimplification but it’s easier to understand like that)

Typedefs over primitive types shouldn’t be that common since there’s not a lot of use for that,
one use case is shortening function type:

typedef SuccessCallback = Int->Int->Void;
typedef ErrorCallback = String->Void;

function doProcess(onSuccess:SuccessCallback, onError:ErrorCallback):Void {}

Another use case is having different implementations:

#if js
typedef TheClass = mypackage.impl.js.TheClass;
#elseif java
typedef TheClass = mypackage.impl.java.TheClass;
#end

Those wouldn’t work it typedef didn’t allow anything that matches it.

If you want a runtime Int that doesn’t unify with an Int at compile time then you need to do what’s described in the blog post:

abstract MyUnrelatedType (Int) {}
1 Like