如何在 Angular HTTP 服务中创建自定义响应库?

How to create a custom response base in Angular HTTP service?

我正在 return 从 Spring Boot API 获取自定义响应,如下所示:

public static ResponseEntity<Object> generateResponse(String message, HttpStatus status, Object responseObj) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("Message", message);
        map.put("Status", status.value());
        map.put("Output", responseObj);

        return new ResponseEntity<Object>(map,status);
    }

它将 return:消息、状态和输出。所以现在我想知道如何在 Angular 中进行自定义响应以接收所有这三个属性。我应该如何替换“???”和?我应该自定义响应基础吗?

public Get(): Observable<Book>{
    return this.http.get< ???<Book> >(this.baseUrl).pipe(map(response => response.Output))
  }

您可以为此使用 generics

interface ApiResponse<T> {
    message: string;
    status: string;
    output: T;
}

interface User {
    id: number;
    username: string;
}

interface BlogPost {
    id: number;
    title: string;
    postedDate: Date;
}

然后您可以拥有 return 和 ApiResponse 某种特定类型的函数。一个普通的打字稿示例:

const getUser = function(): ApiResponse<User> {
    const response: ApiResponse<User> = {
        message: 'test',
        status: 'good',
        output: {
            id: 1,
            username: 'test'
        }
    }
    return response;
} 

const getBlog = function(): ApiResponse<BlogPost> {
    const response: ApiResponse<BlogPost> = {
        message: 'test',
        status: 'good',
        output: {
            id: 1,
            title: 'Stuff!',
            postedDate: new Date()
        }
    }
    return response;
}

如果您知道 output 中的数据也有一些共同的属性,您甚至可以使用 generic constraints 进一步减少打字稿模型中的任何重复。

interface ApiResponse<T extends DbModel> {
    message: string;
    status: string;
    output: T;
}

interface DbModel {
    id: number;
}

interface User extends DbModel {
    username: string;
}

interface ThingThatDoesNotExtendDbModel {
    someField: string;
}

//totally valid
const valid: ApiResponse<User> = { /* fields */};

/*
 * Typescript compile error: Type 'ThingThatDoesNotExtendDbModel' does not satisfy the constraint 
 * 'DbModel'.
 *  Property 'id' is missing in type 'ThingThatDoesNotExtendDbModel' but 
 *   required in type 'DbModel
 */
 const invalid: ApiResponse<ThingThatDoesNotExtendDbModel> = { /*fields*/};