Skip to content

Item 46: Use unknown Instead of any for Values with an Unknown Type

要点

  • The unknown type is a type-safe alternative to any. 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, and unknown.
  • unknown 类型是 any 的类型安全替代品。当你知道有一个值,但不知道或不关心它的类型时,使用 unknown
  • 使用 unknown 强制用户进行类型断言或其他形式的类型收窄。
  • 避免仅返回类型的参数,因为它们可能会带来虚假的安全感。
  • 理解 {}objectunknown 之间的区别。

正文

ts
function parseYAML(yaml: string): any {
  // ...
}

💻 playground


ts
interface Book {
  name: string
  author: string
}
const book: Book = parseYAML(`
  name: Wuthering Heights
  author: Emily Brontë
`)

💻 playground


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

💻 playground


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'

💻 playground


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

💻 playground


ts
interface Feature {
  id?: string | number
  geometry: Geometry
  properties: unknown
}

💻 playground


ts
function isSmallArray(arr: readonly unknown[]): boolean {
  return arr.length < 10
}

💻 playground


ts
function processValue(value: unknown) {
  if (value instanceof Date) {
    value
    // ^? (parameter) value: Date
  }
}

💻 playground


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
  }
}

💻 playground


ts
function safeParseYAML<T>(yaml: string): T {
  return parseYAML(yaml)
}

💻 playground


ts
declare const foo: Foo
let barAny = foo as any as Bar
let barUnk = foo as unknown as Bar

💻 playground

Released under the MIT License.