#### Summary

Just started migrating to axios. I'm wondering why I can't define a type for the response body [for a `DELETE` request](https://github.com/axios/axios/blob/40b829994c2e407109a38a4cf82703261aa3c22c/index.d.ts#L113). The current typing (introduced in #1061) forces inconsistent syntax:

```ts
const { data: foo } = await axios.patch<Foo>(url, data)

// vs (pick your favourite)

const { data: foo } = await axios.delete(url) as AxiosResponse<Foo>
const { data: foo } = await (axios.delete(url) as AxiosPromise<Foo>)
const { data: foo }: AxiosResponse<Foo> = await axios.delete(url)
const foo = (await axios.delete(url)).data as Foo
```

Some consistency would be good here since both use cases appear to be supported equally.

**Additional thoughts**

Although this syntax is nice and terse (and I'm enjoying using it), it is listed in the ["common mistakes" section of DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped#common-mistakes), which I assume are globally applicable rules for typing JS projects.

Specifically:

> If a type parameter does not appear in the types of any parameters, you don't really have a generic function, you just have a disguised type assertion.

The gist of which is that the server can really send back any old object, and there is no way to statically enforce it at TypeScript compile time. So the most "correct" type system to use (given this rule) would be for `data` to always be of type `any`, and force the user to explicitly cast using `as`.

eg.

Here the use of `as` indicates that a type assertion is being made, and that the code cannot be trusted:

```ts
async function getFoo(id: number) {
  const { data } = await axios.get(fooPath(id))
  return data as Foo
}
```

Or if you're really strict about it you can add runtime checks that are backed by the compiler:

```ts
function isFoo(o: any): o is Foo { /* ... */ }

async function getFoo(id: number) {
 const { data } = await axios.get(fooPath(id))
  if (!isFoo(data)) {
    throw new TypeError("That ain't foo!")
  }
  // `data` is now of type `Foo`
  return data
}
```

**cc** @d-fischer

#### Context

- axios version: v0.17.0
- Environment: TypeScript 2.7.1

index.d.ts
en: CancelToken;
  cancel: Canceler;
}
export interface AxiosInterceptorManager<V> {
  use(onFulfilled?: (value: V) => V | Promise<V>, onRejected?: (error: any) => any): number;
  eject(id: number): void;
}
export interface AxiosInstance {
  (config: AxiosRequestConfig): AxiosPromise;
  (url: string, config?: AxiosRequestConfig): AxiosPromise;
  defaults: AxiosRequestConfig;
  interceptors: {
    request: AxiosInterceptorManager<AxiosRequestConfig>;
    response: AxiosInterceptorManager<AxiosResponse>;
  };
  request<T = any>(config: AxiosRequestConfig): AxiosPromise<T>;
  get<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>;
  delete(url: string, config?: AxiosRequestConfig): AxiosPromise;
  head(url: string, config?: AxiosRequestConfig): AxiosPromise;
  post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>;
  put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>;
  patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>;
}
export interface AxiosStatic extends AxiosInstance {
  create(config?: AxiosRequestConfig): AxiosInstance;
  Cancel: CancelStatic;
  CancelToken: CancelTokenStatic;
  isCancel(value: any): boolean;
  all<T>(values: (T | Promise<T>)[]): Promise<T[]>;
  spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;
}
declare const Axios: AxiosStatic;
export default Axios;
