如何在Typescript中使用缺少的字段转换对象?

时间:2016-06-21 03:17:12

标签: typescript

我遇到了Typescript接口的问题。我试图将一个对象(有一些字段丢失,如createdBy)转换为另一个对象,但我的转换不起作用。

我希望有人可以提供帮助。

以下是我的界面文件:

interface IWord {
    ascii?: number;
    awl570?: boolean;
    awl570Sublist?: number;
    categoryId: number;
    frequency?: number;
    groupId: number;
    lessonId: number;
    name: string;
    nawl963?: boolean;
    nawl963D?: number;
    nawl963Sfi?: number;
    nawl963U?: number;
    statusId: number;
    syllables?: string;
    toeflMcG400?: boolean;
    toeic?: boolean;
    wordForms: IWordForm[];
    wordId: number;
    createdById: number;
    createdDate: string;
    modifiedById: number;
    modifiedDate: string;
}

interface IWordForm {
    definition: string;
    posId: number;
    sampleSentences: [ISampleSentence];
    sourceId: number;
    statusId: number;
    synonyms: [ISynonym];
    wordFormId: number;
    wordId: number;
    createdById: number;
    createdDate: string;
    modifiedById: number;
    modifiedDate: string;
}

我正在努力创造这个:

var wos.word = <IWord>{
    categoryId: 1,
    lessonId: 1,
    name: null,
    groupId: 1,
    statusId: Status.Clean,
    toefl: true,
    wordForms: <IWordForm[]>[],
    wordId: $stateParams.wordId
}

但是收到以下错误:

  

严重级代码描述项目文件行抑制状态   错误TS2352都没有输入'{categoryId:number; lessonId:数字;   name:null; groupId:number; statusId:状态; toefl:boo ......'也不打字   'IWord'可分配给另一个。属性'createdById'是   缺少类型'{categoryId:number; lessonId:数字; name:null;   groupId:number; statusId:状态;托福:   嘘......“。 admin C:\ H \ admin \ admin \ app \ routes \ words.ts 102 Active

2 个答案:

答案 0 :(得分:2)

有一个working playground example

好吧,因为表达式word = <IWord>{ ...}的赋值实际上不包含 createdByID,createdDate,modifedById,modifiedDate ,我们应该简单地将它们设为可空

interface IWord {
    ...
    createdById?: number;
    createdDate?: string;
    modifiedById?: number;
    modifiedDate?: string;
}

换句话说 - 要么我们要求Typescript检查我们这些是不可空的......那么我们必须提供它们。或者他们可能会失踪,那么上面的解决方案就是要走的路......

在行动here

中测试它

答案 1 :(得分:1)

TL; DR

var word = <IWord><any>{ name: null };

答案

正如RadimKöhler所指出的那样,如果您的界面不需要这些字段,那么将它们标记为可选字段在语义上是正确的。

interface IWord {
    categoryId: number;
    groupId: number;
    lessonId: number;
    // ...
    createdById?: number; // notice the added question marks
    createdDate?: string;
    modifiedById?: number;
    modifiedDate?: string;
}

或者传递未定义的默认值(就像您已使用name字段一样):

var word = {
    categoryId: 1,
    lessonId: 1,
    name: null,
    // ...
    createdById: undefined,
    createdDate: undefined,
    // ...
}

但是,在某些情况下,您需要创建没有某​​些字段的对象。例如。您想要创建一个基本对象,然后将其传递给其他函数以添加缺少的字段。

在这种情况下,您可以拆分界面:

interface IWordBase {
    // some of the fields that you use internally in your function
    categoryId: number;
    groupId: number;
    lessonId: number;
    frequency?: number;
    // ...
}
interface IWord extends IWordBase {
    // extra fields that are required in the external code, but not necessarily required when creating an object internally
    createdById: number;
    createdDate: string;
    modifiedById: number;
    modifiedDate: string;
}

或者使用hack:

// cast to <any> before casting to <IWord>
var word = <IWord><any>{
    categoryId: 1,
    lessonId: 1,
    name: null
}

请记住,通过使用此hack,您将失去编译时检查的所有好处。如果你某天真的忘记某个字段,编译错误将被取消,你将收到运行时错误。