microsoft / microsoft/TypeScript
Using `undefined` as a discriminator within a mapped type yields erroneous types when primitive intersections are involved
Nessuno ha ancora preso questa issue.
- Lingua principale
- Go
- Stelle
- 111k
- Fork
- 14.4k
- Merge medio
- 1g 19h
- PR unite (30g)
- 117
Descrizione
TypeScript Version: 2.2.0
// A *self-contained* demonstration of the problem follows...
type DeepReadonly<T> = {
readonly [K in keyof T]: DeepReadonly<T[K]>;
}
interface FieldBrand {
" do not use ": void;
}
type FieldId = number & FieldBrand;
interface DefOne {
field: string | FieldId;
kind: string;
}
interface DefTwo {
field?: undefined; // Allow discriminant checks on 'field'
value: string;
}
type Def = DefOne | DefTwo;
interface State {
a?: Def;
b?: Def;
}
type ROState = DeepReadonly<State>;
function lookupName(f: FieldId): string {
return "";
}
function remapFieldsToNames(channels: ROState): ROState {
const newState: State = {};
for (const k of Object.keys(channels)) {
const key = k as keyof ROState;
const ch = channels[key];
let replacement: ROState[typeof key] | undefined = undefined;
if (ch) {
if (ch.field) {
const f = ch.field;
if (typeof f === "number") {
f; // Should be FieldId or number, not never!
replacement = { ...ch, field: lookupName(f) };
}
else if (typeof f === "string") {
f; // correct
}
}
}
newState[k] = replacement || channels[k];
}
return newState;
}
Expected behavior:
There are no type errors in the above, and f after the typeof f === "number" check is either a number or FieldId.
Actual behavior:
replacement = { ...ch, field: lookupName(f) }; has a type error and f is of type never.
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia eseguendo la riproduzione autonoma in TypeScript dell'issue e analizza il narrowing per il tipo DeepReadonly mappato, il discriminatore undefined e l'intersezione di primitivi. La correzione è completata quando la riproduzione non segnala errori di tipo e il ramo number restringe f a number o FieldId invece di never.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- typescript
- Ambito
- compilers
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Tranquilla
- Chiarezza
- Specificata chiaramente
- Idoneità per principianti
- 45/100