具有可空属性的Typescript接口

时间:2018-01-22 09:00:57

标签: javascript typescript

我有一个带有可空字段的接口 IFilterSet

export interface IFilterSet {
        filter1?: boolean;
        filter2?: boolean;
        filter3?: number;
        fitler4?: string;
    }

我收到另一个对象X 可能包含IFilterSet对象等。

我想映射对象X的IFilterSet属性。 第一个问题是为这些属性创建一个循环,但因为它们可以为空,它不会起作用,所以没有任何东西可以循环。 初始化一个空的IFilterSet会破坏那些可以为空的属性的目的,对吧?

3 个答案:

答案 0 :(得分:1)

定义filter1?等可选属性并不意味着将定义值或null。这意味着可以定义(或不​​定义)属性。

假设您收到以下内容:

{
   "name": "foo",
   "type": "bar"
}

你可以像这样使用它:

const filterSet = objectX as IFilterSet;

if (filterSet.filter1 === true) {
    console.log('Do something when filter1 is defined and true');
}
else if (filterSet.filter1 === false) {
    console.log('Do something when filter1 is defined and false');
}
else {
    console.log('filter1 is not true nor false (may be null, undefined or something else)');
}

const value2 = filterSet.filter2 || false;
const value3 = filterSet.filter3 || 0;
console.log('value2 and value3 will always have a value');

对于这些情况,您实际上不需要使用null

如果确实需要在不同的对象中隔离IFilterSet的属性。我建议使用像这样的函数:

const filterSetFrom = (source: any) => {
    const filterSet = {};
    ['filter1', 'filter2', 'filter3', 'filter4']
        .forEach((property) => filterSet[property] = source[property] || null);
    return filterSet;
}; 

答案 1 :(得分:1)

我不确定我是否完全接受了您的问题,但是如何:

function map(filterSet: IFilterSet, obj: X) {
    (obj as any)['filter1'] = filterSet.filter1;
    (obj as any)['filter2'] = filterSet.filter2;
    (obj as any)['filter3'] = filterSet.filter3;
    (obj as any)['filter4'] = filterSet.filter4;
}

这样,X实例将获得filterSet的所有属性,而获取undefined的属性不存在,但所有字段都将在那里结束。

或者这个(如果你试图构建一个新的IFilterSet实例):

function map(obj: X): IFilterSet {
    return {
        filter1: (obj as any)['filter1'],
        filter2: (obj as any)['filter2'],
        filter3: (obj as any)['filter3'],
        filter4: (obj as any)['filter4']
    }
}

在这里,您将获得IFilterSet的实例,其字段为undefinedfilter1filter4的值。

无论哪种方式,您都必须对字段名称进行硬编码,我不确定您是否可以采用不同的方式。

答案 2 :(得分:0)

要使IFilterSet的属性与X的属性一样,您需要做的就是声明X扩展IFilterSet,或者如果可以,则使用类型断言&# 39; t控制X的声明。

class X implements IFilterSet {
    ...
}
...
const x:X = ...
const filterSet = x as IFilterSet;

如果您将IFilterSet的属性设为可选,以服从X的结构,则可以IFilterSet使用必需的属性(不包含?)并拥有 X实施Partial<IFilterSet>Partial<T>为您提供了一个所有属性为T但类型为可选的类型。