Item 71: Use Module Augmentation to Improve Types
May 10, 2024 ยท View on GitHub
Things to Remember
- Use declaration merging to improve existing APIs or disallow problematic constructs.
- Use
voidor error string returns to "knock out" methods and mark them@deprecated. - Remember that overloads only apply at the type level. Don't make the types diverge from reality.## Code Samples
declare let apiResponse: string;
const response = JSON.parse(apiResponse);
const cacheExpirationTime = response.lastModified + 3600;
// ^? const cacheExpirationTime: any
// declarations/safe-json.d.ts
interface JSON {
parse(
text: string,
reviver?: (this: any, key: string, value: any) => any
): unknown;
}
const response = JSON.parse(apiResponse);
// ^? const response: unknown
const cacheExpirationTime = response.lastModified + 3600;
// ~~~~~~~~ response is of type 'unknown'.
interface ApiResponse {
lastModified: number;
}
const response = JSON.parse(apiResponse) as ApiResponse;
const cacheExpirationTime = response.lastModified + 3600; // ok
// ^? const cacheExpirationTime: number
// declarations/safe-response.d.ts
interface Body {
json(): Promise<unknown>;
}
interface SetConstructor {
new <T>(iterable?: Iterable<T> | null): Set<T>;
}
// declarations/ban-set-string-constructor.d.ts:
interface SetConstructor {
new (str: string): void;
}
const s = new Set('abc');
// ^? const s: void
console.log(s.has('abc'));
// ~~~ Property 'has' does not exist on type 'void'.
const otherSet: Set<string> = s;
// ~~~~~~~~ Type 'void' is not assignable to type 'Set<string>'.
interface SetConstructor {
/** @deprecated */
new (str: string): 'Error! new Set(string) is banned.';
}
const s = new Set('abc');
// ^? const s: "Error! new Set(string) is banned."