Reputation: 21501
I am trying to define an API using TypeScript such that it can work like this:
// Create new user (Working)
var user : IUser = new Api.User({ firstName: "John", lastName: "Smith" });
// Delete existing user (Working)
Api.User.Delete(1);
// Load existing user (Unsure how to implement)
var user = Api.User(123);
My TypeScript:
module Api
{
export class User
{
constructor(id : number)
constructor(user : IUser)
constructor(user? : any)
{
// ...
}
static Delete(id : number) {}
}
}
I am not sure how to have a static method Api.User()
i.e. not use new
. I don't know what to call this type of construct, which makes it difficult to research. :(
I did try adding an unnamed static to the User
class, but this isn't right.
static (id : number)
{
// ...
}
Upvotes: 2
Views: 2447
Reputation: 59763
You can export
a function
on the Api
module to retrieve/create a User
instance:
module Api
{
export class User
{
}
export function GetUser(id: number):User {
return new User();
}
// or a slightly different syntax (which generates different JavaScript):
export var Delete = (id: number) => {
};
}
You can't have the class named User
and the function
also be User
, so I've changed it to GetUser
in the example.
You could then call:
Api.GetUser(1234)
or
Api.Delete(1234);
You could also approach this by using an interface if you wanted to limit the ability of
calling code from being able to instantiate instances of the inner class by using an interface instead. Below I've created a simple ISuperUser
interface and and implementation of the class called SuperUserImpl
. As the SuperUserImpl
isn't exported, it's not publicly creatable. This is nice in that you could use simple Api.SuperUser(2345)
to return new instances of a class that implements the ISuperUser
interface.
module Api {
export interface ISuperUser {
id: Number;
name: String;
}
class SuperUserImpl implements ISuperUser
{
constructor(public id: Number) {
}
public name: String;
}
export var SuperUser = (id:Number):ISuperUser => {
return new SuperUserImpl(id);
}
}
var su : Api.ISuperUser = Api.SuperUser(5432);
alert(su.id);
There's a trick that is often used in JavaScript class constructor wherein the function
/constructor for a new object checks to see whether it is of the right type (was the function called or created), and if not created, returns a new instance:
if (!(this instanceof User)) {
return new User(id);
}
While correct, TypeScript when trying to call a constructor with that will cause a compiler warning. This will work, but with the compiler warning:
constructor(id: Number) {
if (!(this instanceof User)) {
return new User(id);
}
}
And later calling:
var u: Api.User = Api.User(543);
A compiler warning suggests, "did you forget to use 'new'?" It does produce valid JavaScript, just with a warning. I'd probably go with the static-like method approach to avoid the TypeScript compiler warning.
Upvotes: 2