Microsoft/TypeScript

in operator typeguard precision loss

Open

#51.339 geöffnet am 28. Okt. 2022

Auf GitHub ansehen
 (2 Kommentare) (0 Reaktionen) (0 zugewiesene Personen)TypeScript (6.726 Forks)batch import
Experience EnhancementHelp WantedSuggestion

Repository-Metriken

Stars
 (48.455 Stars)
PR-Merge-Metriken
 (Durchschn. Merge 6T 17h) (9 gemergte PRs in 30 T)

Beschreibung

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[]>

Contributor Guide