Defining TypeScript type or interface for array within object

I am at the beginning of my TypeScript learning curve and am currently struggling as to how to create an interface (or type?) for an array within an object. This is within a React component. I have the following object:
{
"word": "clumsy",
"phonetic": "/ˈklʌmzi/",
"meanings": [
{
"partOfSpeech": "noun",
"definitions": [
{
"definition": "A clumsy person.",
"synonyms": [],
"antonyms": []
}
],
"synonyms": ["butterfingers", "galoot", "klutz"],
"antonyms": []
},
}
{
"word": "clumsy",
"phonetic": "/ˈklʌmzi/",
"meanings": [
{
"partOfSpeech": "noun",
"definitions": [
{
"definition": "A clumsy person.",
"synonyms": [],
"antonyms": []
}
],
"synonyms": ["butterfingers", "galoot", "klutz"],
"antonyms": []
},
}
I have defined the types for the object like this:
interface dataProps{
word: string;
phonetic: string;
meanings: [];
}
interface dataProps{
word: string;
phonetic: string;
meanings: [];
}
And am implementing them when I create the useState() for this object: const [fetchedData, setFetchedData] = useState<dataProps[]>([]); I am then able to use the strings "word" and "phonetic" without TypeScript yelling at me. I am also able to loop through the array "meanings" using map() and am able to display "partOfSpeech", again without upsetting TypeScript. The issue I have is when It try to do map "definitions": definitions.map((definition) => ( TypeScript kindly informs me that "Property 'map' does not exist on type 'never'" and also that "Parameter 'definition' implicitly has an 'any' type." I understand the reason for the errors but have so far not been able to work out how to define the type(s) for this array and it's data. I have tried adding more types to the interface but can't work out the correct syntax and I have a feeling that I may even need to define them separately. (tagged as React as there is no TypeScript tag)
4 Replies
Joao
Joao2y ago
I would probably just create additional type definitions for those nested objects as well, something like:
type Definition = {
definition: string;
synonyms: string[];
antonyms: string[];
};

type MeaningType = {
partOfSpeech: string;
definitions: Definition[];
synonyms: string[];
antonyms: string[];
};

type dataProps = {
word: string;
phonetic: string;
meanings: MeaningType[];
}
type Definition = {
definition: string;
synonyms: string[];
antonyms: string[];
};

type MeaningType = {
partOfSpeech: string;
definitions: Definition[];
synonyms: string[];
antonyms: string[];
};

type dataProps = {
word: string;
phonetic: string;
meanings: MeaningType[];
}
I'm using type instead of interface here just because of my own preference, there's really no difference.
Chris Bolson
Chris BolsonOP2y ago
That's excellent - worked like a charm. Thanks very much @joao6246
Joao
Joao2y ago
You can take things a bit further when typing strings for which you already know the value of. For example for the partOfSpeech instead of simply type it as string you can tell it which strings in particular are valid:
type MeaningType = {
partOfSpeech: "noun" | "adjective" | "adverb";
definitions: Definition[];
synonyms: string[];
antonyms: string[];
};
type MeaningType = {
partOfSpeech: "noun" | "adjective" | "adverb";
definitions: Definition[];
synonyms: string[];
antonyms: string[];
};
This way you won't misspell it or use something else entirely by accident.
Chris Bolson
Chris BolsonOP2y ago
I see, that makes sense.
Want results from more Discord servers?
Add your server