angular Provide generic type for http request body

gcuhipw9  于 6个月前  发布在  Angular
关注(0)|答案(5)|浏览(44)

与功能请求相关的@angular/*包有哪些?

common

描述

现在我们可以指定POST方法的响应类型,但body被定义为any。我无法为body指定类型。

建议的解决方案

public createUser(userData: UserDataModel): Observable<User> {
  return this.http.post<User, UserData>(url, userData);
}

考虑过的替代方案

我没有其他替代方案。

js81xvg6

js81xvg61#

嘿,@mtvspec ,
设置body参数的类型的目的是什么?你无法访问它,而且根据URL,你可以拥有各种不同的body对象。

flvtvl50

flvtvl502#

嘿,@mtvspec ,
设置body参数的类型的目的是什么?你无法访问它,而且根据URL,你可以拥有各种不同的body对象以提高类型安全性。是的,我可以为每个POST请求创建单独的服务。例如,我使用openapi-typescript包来生成服务API类型,一些服务可以有多个不同的HTTP调用。现在为了使用生成的类型,我为每个HTTP调用创建单独的服务,只是为了向HTTP body提供类型。如果HTTP为body提供类型,我可以直接使用生成的类型。
或者(另一个例子),我可以将服务方法参数转换为body,而不用担心HTTP body类型可能与提供的类型不同。

c8ib6hqw

c8ib6hqw3#

我明白了,但是我还是不明白为什么像http.post这样的通用方法可以依赖于URL来确定一组类型,而其他流行的库,如Axios、Request等,却没有这样的行为。
然而,你可以在http.post周围创建一个 Package 函数,并在其他地方使用这个方法。在那里,你可以定义你的类型,因为你创建了这个 Package 方法。
这是快速示例代码:

type PostParams={
          url: '/user';
          body: {
            username: string;
          };
        }
      | {
          url: '/post';
          body: {
            comment: string;
          };
        }

 
   @Injectable({
      providedIn:'root'
    })
    export class HttpService{
        private http:HttpClient;
        
       post(params:PostParams){
         return this.http.post(params.url,params.body);
       }
    }
    
    //Somewhere else
    this.httpService.post({ url:"/user",body:{username:"admin"} } ) // Here it will insist to have body with username field
2vuwiymt

2vuwiymt4#

@lukaonik 我可以创建一个实现接口的泛型服务并使用它,但我不能理解,主体是否可以像这样具有泛型类型:

post<TResponse, TRequestBody>(..., { ...options, body: TRequestBody }): Observable<TResponse>

这样当我们使用它来严格限制请求体时,就可以作为我们的保护措施。在这种情况下,我无法像这样在服务中提供错误的类型:
无严格请求体类型

type UserData = {
  username: string;
}

public createUser(data: UserData): Observable<User> {
  // But API wants { login: string; } for example, in this case I have error only in runtime
  return this.http.post<User>(this.url, data);
}

有严格请求体类型

// generated.ts or written by hand
export type CreateUserData = {
  login: string;
}

// some-service.ts
import { CreateUserData } from './gererated';

type UserData = {
  username: string;
}

public createUser(data: UserData): Observable<User> {
  // In this case I have error at static type checking
  return this.http.post<User, CreateUserData>(this.url, data);
}
a14dhokn

a14dhokn5#

现在我这样做

public post<TResponse, TBody>(url: string, body: TBody): Observable<TResponse> {
    return this.http.post<TResponse>(url, body);
}

post<User, CreateUserData>(url, data);

这种方法需要为每个HTTP调用创建 Package 器。

相关问题