Skip to content

Latest commit

 

History

History
153 lines (118 loc) · 6.64 KB

never-unknown.md

File metadata and controls

153 lines (118 loc) · 6.64 KB

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

Things to Remember

  • 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.

////## Code Samples

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

💻 playground


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

💻 playground


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


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


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


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

💻 playground


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

💻 playground


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

💻 playground


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


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

💻 playground


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

💻 playground