Set required attributes in TypeScript

But I don't want each time modify this interface by adding and mixing unrelated things to it.

Don't add to or mix unrelated things in the same interface. Create separate interfaces and then combine them when necessary by using intersection types.

interface FirstType {
    id: number;
}

interface SecondType {
    name: string;
}

let myIntersectionObj: FirstType & SecondType = {
    id: 2,
    name: "some string"
};

That's useful in situations like this:

function myFirstFunction(obj: FirstType) { /* does something */ }
function mySecondFunction(obj: SecondType) { /* does something */ }

function myFunction(obj: FirstType & SecondType) {
    myFirstFunction(obj);
    mySecondFunction(obj);
}

myFunction(myIntersectionObj);

Using intersection types helps to make sure everything is typed in the application, which will help prevent mistakes. Indexed types should ideally only be used for key value objects.


You can use an indexer for that:

interface SomeType {
    id: number;
    [key: string]: any;
}

let obj1: SomeType = { name: "OBJ" };           // GOOD ERROR! We must have `id`
let obj2: SomeType = { id: 123 };               // OK
let obj3: SomeType = { id: 123, name: "OBJ" };  // OK

[Playground]

However, please note that even the following code (i.e. with a non-string property key) is valid with the indexer above:

let obj4: SomeType = { id: 123, 1: "OBJ" }; // also OK

which confuses people but it is as it is.


Try like below.

interface SomeType {
    id: number;
    [key: string]: any;
}