microsoft / microsoft/TypeScript
Narrowing of generic this is inconsistent with variable narrowing
- Langage dominant
- Go
- Étoiles
- 111k
- Forks
- 14.3k
- Merge moyen
- 2 j 4 h
- PR mergées (30 j)
- 132
Description
### 🔎 Search Terms
generic union constraint narrowing this
### 🕗 Version & Regression Information
- This is the behavior in every version I tried
### ⏯ Playground Link
https://www.typescriptlang.org/play/?noImplicitReturns=false#code/C4TwDgpgBAKu0F4oEkDMAmKAfKBlYATgNwBQAlgHbAQEBmAhgMbT4FQDeJUUA5gQPYBXMAC4oAIgr8KEcaW4BrSgBMx4gM6E5JAL7kqNBsxQYOXXgOFr1jegBt6BbYpVqyGbXpLKIjBwWhaQQpGYDJpKGB6BQg0dAAKADd7QQgxOIBKMUT+MmVSHz9HQODQ8IooSloaAGkVAB4YAD4klLSOKCUKVVgoHSzYUhIgkLCI6k0YAAsydUaoCAAPam71WHgW4Bn1MRgMs251AHcyYEYpqHit2YA6PiEwfc5ublt1aElpWRFzF6gA4CCAgUeQvN4fGz2RziH5-Q4nM4XK7bG5dZRPX5w8ESTROMQAenxUCkCwIAgIAH5MX9seJ3OgYdS+uY9F4RmVxhBNAAFRz0AC2EGoBHmSxWyjWcEgLX4uwx8NO50u-DulkeBzB9HeEikMkZcP+QqBIMxtMh-n1cOOiqRKrR8oNUDNWgJRJo5IAhEzXlqPvTLX89NxWSRhqUxhUJsAAIJ2Mi+5TTWai5YQVbraXI2ZyjWMaSaKD8KBIa7qUHWxHK1UPB0+7WfPWwuEA42gusQ2wWpt-CtK+J2lS1rG+nEuqCE0me71Okd0jzdl5B5ls8PlSJc4BJ9ToFPiyUbLM7WADOLYKDBHy0SgQZQasi0S6l6vCYsIJAaTvQod5igF5J2VJ0lMEttiIcc3TJfgCExKIYjiQ8MjAid3SgmDtigdR6DCdQry5Ex0CQiDyVNfNgCgRwBCOYtLhPYCmkiUDwMnVC-hbYEGNmQjmOg4NdFDdkI3XHk+UFYUdxgBZU3TKUIBlOUgMwHALwgK8ZFvZ5KgfftnzAV933NL8NVeUioH-QD8Oo-guP4BQYOiWIMH7RCmJszEi0w7DcLWOJrNsmkTIo-gqKQeJaMwBB6Ksly-JeNiKiiidXN4ldRjXKNY3jd5E22cTJL3DNZMPeSLKU7oVOvdTzB-AsixAzjzHvKt7hfN99M-JxvxMsz2lPJAEqJJKXlghyEn4ZzEpi7h3Kw2YvPw3ySN-MjAuCmiFOLSKFtYo12P6wsYpDIA
### 💻 Code
```ts
type Type = I32 | Str;
interface Str {
group: "none";
kind: "str";
}
interface I32 {
group: "scalar";
kind: "i32";
}
declare function takeI32(value: I32): void;
declare function inferKind(value: { kind: T }): T;
function testThis(this: T) {
switch (this.group) {
case "none":
return;
case "scalar":
switch (this.kind) {
case "str": // no error?
case "i32":
}
}
}
function testParameter(o: T) {
switch (o.group) {
case "none":
return;
case "scalar":
switch (o.kind) {
case "str": // error!
case "i32":
}
}
}
function testAliasedThis(this: T) {
const o = this;
switch (o.group) {
case "none":
return;
case "scalar":
switch (o.kind) {
case "str": // error!
case "i32":
}
}
}
function testThis2(this: T): I32 | undefined {
if (this.group === "scalar") {
const value: I32 = this; // error
takeI32(this); // error
this satisfies I32; // error
const arrow = (): I32 => this; // error
return this; // error
}
}
function testParameter2(o: T): I32 | undefined {
if (o.group === "scalar") {
const value: I32 = o; // ok
takeI32(o); // ok
o satisfies I32; // ok
const arrow = (): I32 => o; // ok
return o; // ok
}
}
function testAliasedThis2(this: T): I32 | undefined {
const o = this;
if (o.group === "scalar") {
const value: I32 = o; // ok
takeI32(o); // ok
o satisfies I32; // ok
const arrow = (): I32 => o; // ok
return o; // ok
}
}
```
### 🙁 Actual behavior
The errors (or lack of them) are inconsistent between narrowing `this` directly vs narrowing an "aliased" `this` (`const alias = this;`)
### 🙂 Expected behavior
They should be consistent
### Additional information about the issue
_No response_
Guide de contribution
Ouvrir le guide de contribution
Piste de recherche
Commencez par le TypeScript Playground lié et réduisez les exemples de generic-union fournis pour direct this, aliased this et parameter narrowing. Aucun fichier du dépôt ni aucun test n’étant identifié dans l’issue, localisez le point d’entrée du narrowing du compilateur et ajoutez un regression test couvrant les cas présentés. Le travail est terminé lorsque le narrowing de direct this et de aliased this produit des diagnostics cohérents.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- typescript
- Domaine
- compilers
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- Active
- Clarté
- Plutôt claire
- Accessibilité débutants
- 45/100