mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-08 02:46:15 -05:00
narrow type for generic variables inside TypeQuery (#48434)
This commit is contained in:
@@ -25311,6 +25311,7 @@ namespace ts {
|
||||
// a generic type without a nullable constraint and x is a generic type. This is because when both obj
|
||||
// and x are of generic types T and K, we want the resulting type to be T[K].
|
||||
return parent.kind === SyntaxKind.PropertyAccessExpression ||
|
||||
parent.kind === SyntaxKind.QualifiedName ||
|
||||
parent.kind === SyntaxKind.CallExpression && (parent as CallExpression).expression === node ||
|
||||
parent.kind === SyntaxKind.ElementAccessExpression && (parent as ElementAccessExpression).expression === node &&
|
||||
!(someType(type, isGenericTypeWithoutNullableConstraint) && isGenericIndexType(getTypeOfExpression((parent as ElementAccessExpression).argumentExpression)));
|
||||
|
||||
@@ -71,4 +71,25 @@ tests/cases/compiler/narrowingOfQualifiedNames.ts(38,29): error TS2532: Object i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #48289
|
||||
|
||||
type Fish = { type: 'fish', hasFins: true }
|
||||
type Dog = { type: 'dog', saysWoof: true }
|
||||
|
||||
type Pet = Fish | Dog;
|
||||
|
||||
function handleDogBroken<PetType extends Pet>(pet: PetType) {
|
||||
if(pet.type === 'dog') {
|
||||
const _okay1 = pet.saysWoof;
|
||||
const _okay2: typeof pet.saysWoof = pet.saysWoof;
|
||||
}
|
||||
}
|
||||
|
||||
function handleDogWorking(pet: Pet) {
|
||||
if(pet.type === 'dog') {
|
||||
const _okay1 = pet.saysWoof;
|
||||
const _okay2: typeof pet.saysWoof = pet.saysWoof;
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,27 @@ function init2(foo: DeepOptional) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #48289
|
||||
|
||||
type Fish = { type: 'fish', hasFins: true }
|
||||
type Dog = { type: 'dog', saysWoof: true }
|
||||
|
||||
type Pet = Fish | Dog;
|
||||
|
||||
function handleDogBroken<PetType extends Pet>(pet: PetType) {
|
||||
if(pet.type === 'dog') {
|
||||
const _okay1 = pet.saysWoof;
|
||||
const _okay2: typeof pet.saysWoof = pet.saysWoof;
|
||||
}
|
||||
}
|
||||
|
||||
function handleDogWorking(pet: Pet) {
|
||||
if(pet.type === 'dog') {
|
||||
const _okay1 = pet.saysWoof;
|
||||
const _okay2: typeof pet.saysWoof = pet.saysWoof;
|
||||
}
|
||||
}
|
||||
|
||||
//// [narrowingOfQualifiedNames.js]
|
||||
@@ -94,3 +115,15 @@ function init2(foo) {
|
||||
}
|
||||
}
|
||||
}
|
||||
function handleDogBroken(pet) {
|
||||
if (pet.type === 'dog') {
|
||||
var _okay1 = pet.saysWoof;
|
||||
var _okay2 = pet.saysWoof;
|
||||
}
|
||||
}
|
||||
function handleDogWorking(pet) {
|
||||
if (pet.type === 'dog') {
|
||||
var _okay1 = pet.saysWoof;
|
||||
var _okay2 = pet.saysWoof;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,3 +253,76 @@ function init2(foo: DeepOptional) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #48289
|
||||
|
||||
type Fish = { type: 'fish', hasFins: true }
|
||||
>Fish : Symbol(Fish, Decl(narrowingOfQualifiedNames.ts, 64, 1))
|
||||
>type : Symbol(type, Decl(narrowingOfQualifiedNames.ts, 68, 13))
|
||||
>hasFins : Symbol(hasFins, Decl(narrowingOfQualifiedNames.ts, 68, 27))
|
||||
|
||||
type Dog = { type: 'dog', saysWoof: true }
|
||||
>Dog : Symbol(Dog, Decl(narrowingOfQualifiedNames.ts, 68, 43))
|
||||
>type : Symbol(type, Decl(narrowingOfQualifiedNames.ts, 69, 12))
|
||||
>saysWoof : Symbol(saysWoof, Decl(narrowingOfQualifiedNames.ts, 69, 25))
|
||||
|
||||
type Pet = Fish | Dog;
|
||||
>Pet : Symbol(Pet, Decl(narrowingOfQualifiedNames.ts, 69, 42))
|
||||
>Fish : Symbol(Fish, Decl(narrowingOfQualifiedNames.ts, 64, 1))
|
||||
>Dog : Symbol(Dog, Decl(narrowingOfQualifiedNames.ts, 68, 43))
|
||||
|
||||
function handleDogBroken<PetType extends Pet>(pet: PetType) {
|
||||
>handleDogBroken : Symbol(handleDogBroken, Decl(narrowingOfQualifiedNames.ts, 71, 22))
|
||||
>PetType : Symbol(PetType, Decl(narrowingOfQualifiedNames.ts, 73, 25))
|
||||
>Pet : Symbol(Pet, Decl(narrowingOfQualifiedNames.ts, 69, 42))
|
||||
>pet : Symbol(pet, Decl(narrowingOfQualifiedNames.ts, 73, 46))
|
||||
>PetType : Symbol(PetType, Decl(narrowingOfQualifiedNames.ts, 73, 25))
|
||||
|
||||
if(pet.type === 'dog') {
|
||||
>pet.type : Symbol(type, Decl(narrowingOfQualifiedNames.ts, 68, 13), Decl(narrowingOfQualifiedNames.ts, 69, 12))
|
||||
>pet : Symbol(pet, Decl(narrowingOfQualifiedNames.ts, 73, 46))
|
||||
>type : Symbol(type, Decl(narrowingOfQualifiedNames.ts, 68, 13), Decl(narrowingOfQualifiedNames.ts, 69, 12))
|
||||
|
||||
const _okay1 = pet.saysWoof;
|
||||
>_okay1 : Symbol(_okay1, Decl(narrowingOfQualifiedNames.ts, 75, 13))
|
||||
>pet.saysWoof : Symbol(saysWoof, Decl(narrowingOfQualifiedNames.ts, 69, 25))
|
||||
>pet : Symbol(pet, Decl(narrowingOfQualifiedNames.ts, 73, 46))
|
||||
>saysWoof : Symbol(saysWoof, Decl(narrowingOfQualifiedNames.ts, 69, 25))
|
||||
|
||||
const _okay2: typeof pet.saysWoof = pet.saysWoof;
|
||||
>_okay2 : Symbol(_okay2, Decl(narrowingOfQualifiedNames.ts, 76, 13))
|
||||
>pet.saysWoof : Symbol(saysWoof, Decl(narrowingOfQualifiedNames.ts, 69, 25))
|
||||
>pet : Symbol(pet, Decl(narrowingOfQualifiedNames.ts, 73, 46))
|
||||
>saysWoof : Symbol(saysWoof, Decl(narrowingOfQualifiedNames.ts, 69, 25))
|
||||
>pet.saysWoof : Symbol(saysWoof, Decl(narrowingOfQualifiedNames.ts, 69, 25))
|
||||
>pet : Symbol(pet, Decl(narrowingOfQualifiedNames.ts, 73, 46))
|
||||
>saysWoof : Symbol(saysWoof, Decl(narrowingOfQualifiedNames.ts, 69, 25))
|
||||
}
|
||||
}
|
||||
|
||||
function handleDogWorking(pet: Pet) {
|
||||
>handleDogWorking : Symbol(handleDogWorking, Decl(narrowingOfQualifiedNames.ts, 78, 1))
|
||||
>pet : Symbol(pet, Decl(narrowingOfQualifiedNames.ts, 80, 26))
|
||||
>Pet : Symbol(Pet, Decl(narrowingOfQualifiedNames.ts, 69, 42))
|
||||
|
||||
if(pet.type === 'dog') {
|
||||
>pet.type : Symbol(type, Decl(narrowingOfQualifiedNames.ts, 68, 13), Decl(narrowingOfQualifiedNames.ts, 69, 12))
|
||||
>pet : Symbol(pet, Decl(narrowingOfQualifiedNames.ts, 80, 26))
|
||||
>type : Symbol(type, Decl(narrowingOfQualifiedNames.ts, 68, 13), Decl(narrowingOfQualifiedNames.ts, 69, 12))
|
||||
|
||||
const _okay1 = pet.saysWoof;
|
||||
>_okay1 : Symbol(_okay1, Decl(narrowingOfQualifiedNames.ts, 82, 13))
|
||||
>pet.saysWoof : Symbol(saysWoof, Decl(narrowingOfQualifiedNames.ts, 69, 25))
|
||||
>pet : Symbol(pet, Decl(narrowingOfQualifiedNames.ts, 80, 26))
|
||||
>saysWoof : Symbol(saysWoof, Decl(narrowingOfQualifiedNames.ts, 69, 25))
|
||||
|
||||
const _okay2: typeof pet.saysWoof = pet.saysWoof;
|
||||
>_okay2 : Symbol(_okay2, Decl(narrowingOfQualifiedNames.ts, 83, 13))
|
||||
>pet.saysWoof : Symbol(saysWoof, Decl(narrowingOfQualifiedNames.ts, 69, 25))
|
||||
>pet : Symbol(pet, Decl(narrowingOfQualifiedNames.ts, 80, 26))
|
||||
>saysWoof : Symbol(saysWoof, Decl(narrowingOfQualifiedNames.ts, 69, 25))
|
||||
>pet.saysWoof : Symbol(saysWoof, Decl(narrowingOfQualifiedNames.ts, 69, 25))
|
||||
>pet : Symbol(pet, Decl(narrowingOfQualifiedNames.ts, 80, 26))
|
||||
>saysWoof : Symbol(saysWoof, Decl(narrowingOfQualifiedNames.ts, 69, 25))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,3 +257,76 @@ function init2(foo: DeepOptional) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #48289
|
||||
|
||||
type Fish = { type: 'fish', hasFins: true }
|
||||
>Fish : Fish
|
||||
>type : "fish"
|
||||
>hasFins : true
|
||||
>true : true
|
||||
|
||||
type Dog = { type: 'dog', saysWoof: true }
|
||||
>Dog : Dog
|
||||
>type : "dog"
|
||||
>saysWoof : true
|
||||
>true : true
|
||||
|
||||
type Pet = Fish | Dog;
|
||||
>Pet : Pet
|
||||
|
||||
function handleDogBroken<PetType extends Pet>(pet: PetType) {
|
||||
>handleDogBroken : <PetType extends Pet>(pet: PetType) => void
|
||||
>pet : PetType
|
||||
|
||||
if(pet.type === 'dog') {
|
||||
>pet.type === 'dog' : boolean
|
||||
>pet.type : "fish" | "dog"
|
||||
>pet : Pet
|
||||
>type : "fish" | "dog"
|
||||
>'dog' : "dog"
|
||||
|
||||
const _okay1 = pet.saysWoof;
|
||||
>_okay1 : true
|
||||
>pet.saysWoof : true
|
||||
>pet : Dog
|
||||
>saysWoof : true
|
||||
|
||||
const _okay2: typeof pet.saysWoof = pet.saysWoof;
|
||||
>_okay2 : true
|
||||
>pet.saysWoof : true
|
||||
>pet : Dog
|
||||
>saysWoof : true
|
||||
>pet.saysWoof : true
|
||||
>pet : Dog
|
||||
>saysWoof : true
|
||||
}
|
||||
}
|
||||
|
||||
function handleDogWorking(pet: Pet) {
|
||||
>handleDogWorking : (pet: Pet) => void
|
||||
>pet : Pet
|
||||
|
||||
if(pet.type === 'dog') {
|
||||
>pet.type === 'dog' : boolean
|
||||
>pet.type : "fish" | "dog"
|
||||
>pet : Pet
|
||||
>type : "fish" | "dog"
|
||||
>'dog' : "dog"
|
||||
|
||||
const _okay1 = pet.saysWoof;
|
||||
>_okay1 : true
|
||||
>pet.saysWoof : true
|
||||
>pet : Dog
|
||||
>saysWoof : true
|
||||
|
||||
const _okay2: typeof pet.saysWoof = pet.saysWoof;
|
||||
>_okay2 : true
|
||||
>pet.saysWoof : true
|
||||
>pet : Dog
|
||||
>saysWoof : true
|
||||
>pet.saysWoof : true
|
||||
>pet : Dog
|
||||
>saysWoof : true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,4 +64,25 @@ function init2(foo: DeepOptional) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #48289
|
||||
|
||||
type Fish = { type: 'fish', hasFins: true }
|
||||
type Dog = { type: 'dog', saysWoof: true }
|
||||
|
||||
type Pet = Fish | Dog;
|
||||
|
||||
function handleDogBroken<PetType extends Pet>(pet: PetType) {
|
||||
if(pet.type === 'dog') {
|
||||
const _okay1 = pet.saysWoof;
|
||||
const _okay2: typeof pet.saysWoof = pet.saysWoof;
|
||||
}
|
||||
}
|
||||
|
||||
function handleDogWorking(pet: Pet) {
|
||||
if(pet.type === 'dog') {
|
||||
const _okay1 = pet.saysWoof;
|
||||
const _okay2: typeof pet.saysWoof = pet.saysWoof;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user