typescript 如何在具有嵌套数组的接口中允许新属性

to94eoyn  于 2023-11-20  发布在  TypeScript
关注(0)|答案(2)|浏览(156)

我有一个接口,在该接口中有一个名为data的属性,它是一个数组。所以看起来像这样:

type Data = { prop1: string; prop2: string }[]; 

interface MyInterface {
  prop1: string;
  data: Data;
}

字符串
现在我有一个RxJS流,
在这个流中,接口是MyInterface
现在我想在data属性中显示一些稍微不同的东西。

type DataExtended = Data & {
  newValue: string
}


将该新类型添加到扩展接口

interface MyInterfaceExtended extends MyInterface {
  data: DataExtended
}


现在,在控制器中,我调用了一个HTTP服务,该服务的预期结果是MyInterface。但是我需要更改该数据结构,所以我有以下内容:

var myData$ = Observable<MyInterfaceExtended>;

constructor(private myService:myservice){
  this.myData$ = this.myService.get().pipe((map(value)) => {
      foreach(value.data,  (data) =>{
        data.newValue = 'new';
      })
      return value
  })
}


但我一直得到错误说:
类型{etc}上不存在“newValue”
为什么会这样?

e5nqia27

e5nqia271#

假设:

假设this.myService.get()返回Observable<MyInterface>
DataExtended类型有一个问题,因为您将Data{ prop1: string; prop2: string }类型的数组)与对象{ newValue: string }组合在一起时,合并。
正确的类型应该是:

type DataExtended = Data &
  {
    newValue: string;
  }[];

字符串
现有的类型。
或者你应该将Data定义为单个对象而不是数组类型。

新增类型:

type Data = { prop1: string; prop2: string };

interface MyInterface {
  prop1: string;
  data: Data[];
}

type DataExtended = Data &
  {
    newValue: string;
  };

interface MyInterfaceExtended extends MyInterface {
  data: DataExtended[];
}


要使用map RxJS运算符转换数据,可以使用以下命令实现:

现有类型的解决方案1:

this.myData$ = this.myService.get()
  .pipe(
    map((response: any) => {
      let newResponse: MyInterfaceExtended = response;

      newResponse.data = newResponse.data.map((x) => ({
        ...x,
        newValue: 'new',
      }));

      return newResponse;
    })
  );

新类型的解决方案2:

this.myData$ = this.myService.get()
  .pipe(
    map(
      (response: any) =>
        ({
          data: response.data.map(
            (x: Data) =>
              ({
                ...x,
                newValue: 'new',
              } as DataExtended)
          ),
        } as MyInterfaceExtended)
    )
  );


Demo @ StackBlitz

h5qlskok

h5qlskok2#

这是如何创建泛型接口。

interface BaseUserDetails<TID = number> {
  id: TID;
  firstName: string;
  lastName: string;
}

interface UserWithContacts extends BaseUserDetails<number> {
  phone: string;
}

interface User<TUserDetail> {
  details: TUserDetail;
}

const baseUser: User<BaseUserDetails> = {
  details: {
    id: 1,
    firstName: 'first name',
    lastName: 'last name',
  },
};

const userWithContact: User<UserWithContacts> = {
  details: {
    id: 1,
    firstName: 'first name',
    lastName: 'last name',
    phone: '--- --- -- --',
  },
};

字符串

另一个例子

interface BaseEntity<ID> {
  id: ID;
}

interface SelectIDField<T, K extends keyof T = keyof T> {
  idField: K;
}

interface UserEntity
  extends BaseEntity<number>,
    SelectIDField<UserEntity, 'uuid' | 'username'> {
  uuid: string;
  username: string;
  password: string;
}

相关问题