具有未知属性键的typescript接口定义

gcuhipw9  于 2023-01-18  发布在  TypeScript
关注(0)|答案(4)|浏览(192)

如何表达接口(IResponse),其中一个属性具有字符串键(静态情况下是未知的)。下面,键values可以是bookschairs,所有其他键和类型都是静态已知的。下面的实现给出了错误。我猜错误是因为IResponse上的索引签名使所有属性值都是IValue[]。有办法做到这一点吗?

export interface IMeta{}
export interface IValue{}
export interface IResponse {
     meta: IMeta;
     [index: string]:IValue[];
}

 export class Response implements IResponse {
    meta:IMeta;
    values:IValue[];
    //books:IValue[];
    //anything:IValue[];
 }
a1o7rhls

a1o7rhls1#

老问题,但这里是我如何解决自己的问题。

export interface Foo {
    [key: string]: any;
}

{ something: 0 } as Foo => valid

{ other: 'hello' } as Foo => valid

编辑:2023年1月14日:如果您知道可能的形状是什么,则有一种更好的方法来实现类型安全:

type ApiResponse<Type> = {
  [Property in keyof Type]: Type[Property];
};

type BookResponse = { title: string; }

const myBookResponse: ApiResponse<BookResponse> = { title: 'foo' } // OK
const myBookResponse: ApiResponse<BookResponse> = { title: 42 } // ERROR
const myBookResponse: ApiResponse<BookResponse> = { title: 'foo', taco: true } // ERROR
5uzkadbs

5uzkadbs2#

如果您为已知类型定义一个接口,为“未知”类型定义一个单独的接口,则可以使用类型Assert来告诉编译器您要使用的接口。
这并不理想,但您正在一个边缘情况下工作(即不完全动态,也不完全静态)。

export interface IMeta{}
export interface IValue{}
export interface IFunkyResponse {
     [index: string]:IValue[];
}
export interface IResponse {
     meta: IMeta;
}

export class Response implements IResponse {
    meta:IMeta;
    values:IValue[];
    books:IValue[];
    anything:IValue[];
}

您可以在<IResponse> resp<IFunkyResponse> resp之间使用type-assert来访问其中一个样式。

zvokhttg

zvokhttg3#

无接口:

const myFunc = ((myObjectWithSomeKeys: { [key: string]: any }) => {
});
0ejtzxu1

0ejtzxu14#

不幸的是,似乎没有确切的答案,只有近似的解。
解决方案是在两个接口上使用交集类型,一个定义静态元数据,另一个定义动态键:

interface IStatic {
  staticflag: boolean;
}

interface IDynamic {
  [x: string]: string | number;
}

type Complex = IStatic & IDynamic;

const a: Complex = {
  staticflag: false,
  dynamic1: 'a',
};

相关问题