[Typescript] Making TypeScript Stick - 3

1.

const values = [3, "14", [21]]
for (let a in values) {
  //     ^?
}
for (let b of values) {
  //     ^?
}

.

.

.

.

Answer:

for...in loop: The for...in statement iterates over all enumerable properties of an object that are keyed by strings (ignoring ones keyed by Symbols), including inherited enumerable properties. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

for..of loop: The for...of statement creates a loop iterating over iterable objects, including: built-in StringArray, array-like objects (e.g., arguments or NodeList), TypedArrayMapSet, and user-defined iterables. It invokes a custom iteration hook with statements to be executed for the value of each distinct property of the object. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of

For ..in: use string key, so that `a` is string type

For ..of: `b` will be each value, so will be `number | string | number[]`

 

 

2.

class Person {
  constructor(public name: string) {}
}
class Library {
  librarians: Person[] = []
}
const localLibrary = Library
//       ^?
const otherLibrary = new Library()
//       ^?

.

.

.

.

Answer:

const localLibrary: typeof Library
const otherLibrary: Library

 

 

 

3.

class AsyncManager {
  constructor(arg: 0 | 4 | string) {
    if (arg > 0 || arg <= 0) {
      new Promise((resolve, reject) => {
        arg
        //^?
      })
    }
  }
}

.

.

.

.

Answer:

(parameter) arg: string | 0 | 4
// "4" > 0 --> true

If doing this, will restrict `arg` type:

    if (typeof arg === "number" && (arg > 0 || arg <= 0)) {
      new Promise((resolve, reject) => {
        arg
        //^?
      })
    }
arg: string | 0 | 4

 

 

4.

enum CoinResult {
  heads,
  tails,
}
function flipCoin(): CoinResult {
  return Math.random() > 0.5
    ? CoinResult.heads
    : CoinResult.tails
}
function main() {
  const flipResult = flipCoin()
  if (flipResult === CoinResult.heads) {
    console.log("heads")
  } else if (flipResult === CoinResult.tails) {
    console.log("tails")
  } else {
    flipResult
    // ^?
  }
}

.

.

.

.

Answer:

const flipResult: never

 

 

 

5.

function getValue(): [number] | Promise<number> {
  if (Math.random() > 0.5) return [42]
  else return Promise.resolve(42)
}
async function main() {
  const resolved = await getValue()
  //     ^?
}

.

.

.

.

Answer:

const resolved: number | [number]

 

 

 

6.

let x: number | any = 41
const y = x
//    ^?

.

.

.

.

Answer:

let x = 41 // x: number
const x = 41 // x: 41
// but say that x is a number type
const x: number = 41 // x: number
// if say taht x can be any type as well
const x: number | any = 41 // x: any
// Union type, if you union any type with `any`, the type will be `any`
const y = x // y: any

---
      
let x = 41
const y = x; //y: number, y will infer as number

---
const x = 41
const y = x; // y: 41

 

 

 

7.

const values = [4, 1, null, 21, 45, 32]
const filtered = values.filter((val) => val !== null)
//            ^?

.

.

.

.

Answer:

const filtered: (number | null)[]

If you just want number[], you need to use type guard function:

function isNumber<T>(x: T | undefined | null): x is T {
    return typeof x === "number"
}

const filtered = values.filter(isNumber) // number[]

 

 

 

8.

class Person {
  static species = "Homo Sapien"
  constructor(public name: string) {}
}
const p = new Person("mike")
let x: keyof typeof Person
//  ^?
let y: keyof typeof p
//  ^?

.

.

.

.

.

Answer:

let x: "prototype" | "species"
let y: "name"

static prop cannot be access by instance, therefore y doesn't contains "species".

 

 

9.

enum Language {
  JavaScript,
  TypeScript = "TS",
}
let lang1: Language = Language.JavaScript
//   ^?
let lang2: Language = Language.TypeScript
//   ^?
Math.round(lang1)
Math.round(lang2)

.

.

.

.

Answer:

// ERROR 
Math.round(lang2) // Argument of type 'Language' is not assignable to parameter of type 'number'.

 

 

 

10.

async function tryFetch(url: RequestInfo) {
  try {
    const val = await (await fetch(url)).json()
    return val
  } catch (err) {
    console.error(err)
    return undefined
  }
}
async function main() {
  const val = await tryFetch("https://example.com")
  //    ^?
}

.

.

.

.

Answer:

const val: any

If change:

const val = await (await fetch(url)).json() as string

Then:

const val: string | undefined

 

If change:

async function tryFetch(url: RequestInfo) {
  try {
    const val = await (await fetch(url)).json() 
    throw new Error("err")
  } catch (err) {
    console.error(err)
    return undefined
  }
}

Then:

const val: undefined

which comes from catch block `return undefined`.

 

If change:

async function tryFetch(url: RequestInfo) {
  try {
    const val = await (await fetch(url)).json() 
    throw new Error("err")
  } catch (err) {
    console.error(err)
    if (err instanceof Error) {
       throw err
    } else {
       throw new Error("err")
    }
  }
}

Then:

const val: void

because we don't do return from catch block, therefore val never get assignmenet.

We need to do try-catch block again.

 

 

 

11.

class Book {
  title: string = ""
  author: string = ""
}
const keys = Object.keys(new Book())
//      ^?

.

.

.

.

Answer:

const keys: string[]

 

posted @ 2022-07-26 14:24  Zhentiw  阅读(37)  评论(0编辑  收藏  举报