TypeScript - Cannot be strict with types wihen defining an instance on the fly

I have the following TypeScript code which compiles properly.

My goal here is to be strict on terms of types.

When defining user1 instance I get this effect successfully. I mean, I'm forced to define all the members for IUser. For example, if I don't specify the id property for user1, then when I try to compile, the TypeScript linter throws the following error:

TSError: тип Unable to compile TypeScript:
error TS2322: Type '{ username: string; password: string; email: string; age: number; }' is not assignable to type 'IUser'.
  Property 'id' is missing in type '{ username: string; password: string; email: string; age: number; }'.

But in the other hand, as you can see for the user corresponding to: Steve Jobs I didn't used the property: id but the linter doesn't throw any error.

I'm looking for a way to define a user on the fly like that second user (not declaring another variable like the first user) and be strict with the types at the same time. I tried with the angle brackets with no success.

interface IUser {
    id: number;
    username: string;
    password: string;
    email: string;
    age: number;
}

let user1: IUser = {
    id: 1,
    username: 'Bill Gates',
    password: 'windows',
    email: 'billgates@microsoft.com',
    age: 61
};

var outputObject = function(obj: any) {
    console.log(JSON.stringify(obj));
}

outputObject(user1);

outputObject(<IUser> {
    username: 'Steve Jobs',
    password: 'mac',
    email: 'stevejobs@apple.com',
    age: 62
});

Any idea on how to get this work?

Thanks!

1 answer

  • answered 2018-07-11 04:45 Titian Cernicova-Dragomir

    It's a bit unclear from your question, but it appears you are looking form Partial<T>. Partial<T> transforms the type T to have all properties optional. You can use Partial<IUser> as the parameter to outputObject, or we can keep outputObject and add a generic parameter to it that we can then specify explicitly as Partial<IUser> to get checking on the parameter passed in :

    var outputObject = function<T>(obj: T) {
        console.log(JSON.stringify(obj));
    }
    
    outputObject<Partial<IUser>>({
        username: 'Steve Jobs',
        password: 'mac',
        email: 'stevejobs@apple.com',
        age: 62
    });
    
    outputObject<Partial<IUser>>({
        age: '62' // Error incompatible types
    });