How can I define an array of objects?
#1
I've come across a situation where I need to define an array of objects in TypeScript with strict typing. My current implementation looks like this:

Code:
"0": {
        "id": 0,
        "name": "Available"
    },
    "1": {
        "id": 1,
        "name": "Ready"
    },
    "2": {
        "id": 2,
        "name": "Started"
    }
};

However, the issue with the above code is that it does not provide strict type-checking for the userTestStatus object. For example, if I were to make a typo in one of the object properties, TypeScript wouldn't notify me of the error. What I want to achieve is to have TypeScript check the correctness of both the structure and the types within the userTestStatus object, and report any inconsistencies or typos. Also, I need to figure out whether it's possible to define the structure inline or if I need to create separate type definitions.
Let’s say I accidentally try to access a non-existent property like userTestStatus[3].nammme, TypeScript should flag this as an error. Could you please assist by providing the correct type definition for this case?
Reply
#2
To solve this problem, you should define a type for the objects within your collection, and then use that type to define the structure of your userTestStatus object.
Here's an example of how you can do this:

Code:
type TestStatus = {
    id: number;
    name: string;
};
type UserTestStatus = {
    [key: string]: TestStatus;
};
let userTestStatus: UserTestStatus = {
    "0": {
        "id": 0,
        "name": "Available"
    },
    "1": {
        "id": 1,
        "name": "Ready"
    },
    "2": {
        "id": 2,
        "name": "Started"
    }
};

The UserTestStatus type is an index signature that implies that every property key within the userTestStatus object must be a string, and the value must be of the type TestStatus. This way, you have strictly typed each property inside userTestStatus. Now, TypeScript will alert you if you try to access a property that does not exist or access an object property that is mistyped.
Reply
#3
Implementing your suggestion provides a good type structure, but the types could imply that keys can be any arbitrary strings, whereas the actual keys are known and limited to "0", "1", and "2". Is there a way to restrict the keys to only those values?
Reply
#4
Yes, you can use a Record type to map a limited set of known keys to their corresponding types like this:

Code:
type TestStatus = {
    id: number;
    name: string;
};
type UserTestStatusKeys = "0" | "1" | "2";
type UserTestStatus = Record < UserTestStatusKeys, TestStatus > ;
let userTestStatus: UserTestStatus = {
    "0": {
        "id": 0,
        "name": "Available"
    },
    "1": {
        "id": 1,
        "name": "Ready"
    },
    "2": {
        "id": 2,
        "name": "Started"
    }
};

Now your userTestStatus will only accept the keys "0", "1", and "2". Any attempt to use an undefined key would result in a TypeScript error.
Reply
#5
That seems to address the constraints effectively. For completeness, here is the fully working code that ensures the correct type declaration of the userTestStatus object:

Code:
type TestStatus = {
    id: number;
    name: string;
};
type UserTestStatusKeys = "0" | "1" | "2";
type UserTestStatus = Record < UserTestStatusKeys, TestStatus > ;
let userTestStatus: UserTestStatus = {
    "0": {
        "id": 0,
        "name": "Available"
    },
    "1": {
        "id": 1,
        "name": "Ready"
    },
    "2": {
        "id": 2,
        "name": "Started"
    }
};
// Example usage:
console.log(userTestStatus["0"].name); // Correct usage, will output "Available"
// console.log(userTestStatus["3"].nammme); // Incorrect usage, TypeScript will flag this as an error
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)