Roy - Type Aliases
Roy now has a form of type aliasing. You can give names to types, like so:
type Name = String
type Animal = {name: Name, legs: Number}
let zebra: Animal = {name: "Zebra", legs: 4}
The benefits are mainly for structural types:
- You don’t have to type out a long structure whenever you want to be explicit
- Better error messages
For example, this is a poorly typed program without an alias:
let getName x = x.firstName ++ x.lastName
console.log (getName {})
And this is the error message:
Type error: {} is not {firstName: String, lastName: String}
You can imagine the error would be kind of scary if the structure was heavily nested or had more than just a couple of elements.
This is a poorly typed program with an alias:
type Person = {firstName: String, lastName: String}
let getName (x: Person) = x.firstName ++ x.lastName
console.log (getName {})
And this is the nicer error message:
Type error: {} is not Person
I originally wanted inference to use the scope to check which aliases it could satisfy and use the most appropriate:
type Person = {firstName: String, lastName: String}
// `x` is inferred to be Person from the scope
let getName x = x.firstName ++ x.lastName
Which is something that Yeti is able to do. Instead, I implemented a very simple version that will just propogate explicit aliases. Using the simple version might conflict with my future plans.
Later on I hope to be able to use the type aliases to output nicer JavaScript:
// Roy: type Person = {firstName: String, lastName: String}
var Person = function(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
};
And I might even be able to extend aliases to output information about the hierarchy:
// Hypothetical Roy: type Employee = Person with {wage: Number}
var Employee = function(firstName, lastName, wage) {
Person.call(this, firstName, lastName);
this.wage = wage;
};
// Just for documentation:
Employee.prototype = new Person();
But maybe not. I’ll have to try it out.
In adding aliases, I fixed something that I wanted to do for a while; using structural types for normal type annotations:
let getName (x: {name: String}) = x.name
console.log (getName {name: "TEST"})
Let me know what you think.