Item 71: Use Module Augmentation to Improve Types
要点
- Use declaration merging to improve existing APIs or disallow problematic constructs.
- Use
void
or 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.
- 使用声明合并来改进现有的 API 或禁止问题构造。
- 使用
void
或错误字符串返回值来“废弃”方法,并标记为@deprecated
。 - 记住,重载只适用于类型层面。不要让类型与实际情况不一致。
正文
ts
declare let apiResponse: string
ts
const response = JSON.parse(apiResponse)
const cacheExpirationTime = response.lastModified + 3600
// ^? const cacheExpirationTime: any
ts
// declarations/safe-json.d.ts
interface JSON {
parse(
text: string,
reviver?: (this: any, key: string, value: any) => any
): unknown
}
ts
const response = JSON.parse(apiResponse)
// ^? const response: unknown
const cacheExpirationTime = response.lastModified + 3600
// ~~~~~~~~ response is of type 'unknown'.
ts
interface ApiResponse {
lastModified: number
}
const response = JSON.parse(apiResponse) as ApiResponse
const cacheExpirationTime = response.lastModified + 3600 // ok
// ^? const cacheExpirationTime: number
ts
// declarations/safe-response.d.ts
interface Body {
json(): Promise<unknown>
}
ts
interface SetConstructor {
new <T>(iterable?: Iterable<T> | null): Set<T>
}
ts
// declarations/ban-set-string-constructor.d.ts:
interface SetConstructor {
new (str: string): void
}
ts
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>'.
ts
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."