Item 46: Use unknown Instead of any for Values with an Unknown Type
要点
- The
unknown
type is a type-safe alternative toany
. Use it when you know you have a value but do not know or do not care what its type is. - Use
unknown
to force your users to use a type assertion or other form of narrowing. - Avoid return-only type parameters, which can create a false sense of security.
- Understand the difference between
{}
,object
, andunknown
. unknown
类型是any
的类型安全替代品。当你知道有一个值,但不知道或不关心它的类型时,使用unknown
。- 使用
unknown
强制用户进行类型断言或其他形式的类型收窄。 - 避免仅返回类型的参数,因为它们可能会带来虚假的安全感。
- 理解
{}
、object
和unknown
之间的区别。
正文
ts
function parseYAML(yaml: string): any {
// ...
}
ts
interface Book {
name: string
author: string
}
const book: Book = parseYAML(`
name: Wuthering Heights
author: Emily Brontë
`)
ts
const book = parseYAML(`
name: Jane Eyre
author: Charlotte Brontë
`)
console.log(book.title) // No error, logs "undefined" at runtime
book('read') // No error, throws "book is not a function" at runtime
ts
function safeParseYAML(yaml: string): unknown {
return parseYAML(yaml)
}
const book = safeParseYAML(`
name: The Tenant of Wildfell Hall
author: Anne Brontë
`)
console.log(book.title)
// ~~~~ 'book' is of type 'unknown'
book('read')
// Error: 'book' is of type 'unknown'
ts
const book = safeParseYAML(`
name: Villette
author: Charlotte Brontë
`) as Book
console.log(book.title)
// ~~~~~ Property 'title' does not exist on type 'Book'
book('read')
// Error: This expression is not callable
ts
interface Feature {
id?: string | number
geometry: Geometry
properties: unknown
}
ts
function isSmallArray(arr: readonly unknown[]): boolean {
return arr.length < 10
}
ts
function processValue(value: unknown) {
if (value instanceof Date) {
value
// ^? (parameter) value: Date
}
}
ts
function isBook(value: unknown): value is Book {
return (
typeof value === 'object' &&
value !== null &&
'name' in value &&
'author' in value
)
}
function processValue(value: unknown) {
if (isBook(value)) {
value
// ^? (parameter) value: Book
}
}
ts
function safeParseYAML<T>(yaml: string): T {
return parseYAML(yaml)
}
ts
declare const foo: Foo
let barAny = foo as any as Bar
let barUnk = foo as unknown as Bar