Reputation: 24562
I have the following Typescript interface files and I am trying to create a simple minimal object of type Word with a WordForm object inside of it:
interface IWord {
categoryId: number;
createdBy: number;
createdDate: any;
groupId: number;
ielts: boolean;
lessonId: number;
modifiedBy: number;
modifiedDate: any;
toefl: boolean;
toeic: boolean;
wordForms: IWordForm[];
wordId: string;
}
interface IWordForm {
createdBy: number;
createdDate: any;
definition: string;
modifiedBy: number;
modifiedDate: any;
posId: number;
primary: boolean;
sample1: string;
sample2: string;
sample3: string;
sample4: string;
sample5: string;
synoym: string;
wordFormId: string;
wordId: string;
}
This works okay:
wos.word = <IWord>{
categoryId: 1,
lessonId: 1,
groupId: 1,
toefl: true
}
But this give me an error:
wos.word = <IWord>{
categoryId: 1,
lessonId: 1,
groupId: 1,
toefl: true,
wordForm: <IWordForm>{
posId: 1
}
}
Severity Code Description Project File Line Suppression State Error TS2352 Neither type '{ categoryId: number; lessonId: number; groupId: number; toefl: boolean; wordForm: IWordForm; }' nor type 'IWord' is assignable to the other. Property 'createdBy' is missing in type '{ categoryId: number; lessonId: number; groupId: number; toefl: boolean; wordForm: IWordForm; }'. admin C:\H\admin\admin\app\routes\words.ts 76 Active
Severity Code Description Project File Line Suppression State Error Build: Neither type '{ categoryId: number; lessonId: number; groupId: number; toefl: boolean; wordForm: IWordForm; }' nor type 'IWord' is assignable to the other. admin C:\H\admin\admin\app\routes\words.ts 76
Can someone help and tell me how I can create a word object with a word form inside of it? Note that I know a lot of the parameters are missing in my assignment but by casting I think this should still work.
Upvotes: 0
Views: 42
Reputation: 13216
In your specific case, the issue is that the interface has a wordForms property that takes a list of IWordForm, but you've provided a wordForm (singular) property, with a single word form, not a list. If you rename it and wrap your form in a list it should work:
wos.word = <IWord> {
categoryId: 1,
lessonId: 1,
groupId: 1,
toefl: true,
wordForms: [{
posId: 1
}]
}
More generally, that's not how casting works. Casting won't help in cases like this; when you cast something you're promising that it has the type you provide, and that's fine if it's possible you're right (e.g. casting string|number
to number
), but TypeScript won't allow it if it knows you're definitely wrong (casting string to number), only if it's possible that you're right.
If you need to avoid this normally, you can force TypeScript to accept your correctness by casting to any
first though, as below. Don't do this without good reason! (Stubs/mocks in tests are one of few good reasons I know):
wos.word = <IWord> <any> {
categoryId: 1,
lessonId: 1,
groupId: 1,
toefl: true,
wordForm: <IWordForm>{
posId: 1
}
}
Upvotes: 2
Reputation: 3455
Make each property "nullable" (with a question mark).
interface IWord {
categoryId?: number;
createdBy?: number;
createdDate?: any;
groupId?: number;
ielts?: boolean;
lessonId?: number;
modifiedBy?: number;
modifiedDate?: any;
toefl?: boolean;
toeic?: boolean;
wordForms?: IWordForm[];
wordId?: string;
}
interface IWordForm {
createdBy?: number;
createdDate?: any;
definition?: string;
modifiedBy?: number;
modifiedDate?: any;
posId?: number;
primary?: boolean;
sample1?: string;
sample2?: string;
sample3?: string;
sample4?: string;
sample5?: string;
synoym?: string;
wordFormId?: string;
wordId?: string;
}
and wordForms is an array:
wordForms: [{
posId: 1
}]
And..you probably don't need to cast types as you type.
Upvotes: 1