Microsoft/TypeScript

in operator typeguard precision loss

Open

#51 339 ouverte le 28 oct. 2022

Voir sur GitHub
 (2 commentaires) (0 réactions) (0 assignés)TypeScript (6 726 forks)batch import
Experience EnhancementHelp WantedSuggestion

Métriques du dépôt

Stars
 (48 455 stars)
Métriques de merge PR
 (Merge moyen 6j 17h) (9 PRs mergées en 30 j)

Description

Bug Report

🔎 Search Terms

🕗 Version & Regression Information

v4.9.0 v4.9.1 5.0.0-dev.20221101

⏯ Playground Link

Playground link with relevant code

💻 Code

function addressOrThrow(value: unknown) {
  if (typeof value !== "object" || value == null) throw new TypeError();

  if (!("street" in value) || typeof value.street !== "string")
    throw new TypeError();

  if (!("houseNumber" in value) || typeof value.houseNumber !== "number")
    throw new TypeError();

  return value;
}

function addressOrThrowTG(value: unknown): value is Address {
  addressOrThrow(value);
  return true;
}

function personOrThrow(value: unknown) {
  if (typeof value !== "object" || value == null) throw new TypeError();

  if (!("firstName" in value) || typeof value.firstName !== "string")
    throw new TypeError();

  if (!("lastName" in value) || typeof value.lastName !== "string")
    throw new TypeError();

  if ("middleName" in value && typeof value.middleName !== "string")
    throw new TypeError();

  if (!("addresses" in value) || !Array.isArray(value.addresses))
    throw new TypeError();

  if (!value.addresses.every(addressOrThrowTG))
    throw new TypeError();

  return value;
}

type Address = ReturnType<typeof addressOrThrow>;

type Person = ReturnType<typeof personOrThrow>;

🙁 Actual behavior

type Address = object & Record<"street", unknown> & Record<"houseNumber", unknown> type Person = object & Record<"firstName", unknown> & Record<"lastName", unknown> & Record<"addresses", unknown>

🙂 Expected behavior

type Address = object & Record<"street", string> & Record<"houseNumber", number> type Person = object & Record<"firstName", string> & Partial<Record<"middleName", string>> & Record<"lastName", string> & Record<"addresses", Address[]>

Guide contributeur