Properly check singleton labeled tuple before unwrapping (#48554)

* properly check if singleton labeled tuple has optional element

* also check if labeled element is rest
This commit is contained in:
Gabriela Araujo Britto 2022-04-04 19:53:41 -03:00 committed by GitHub
parent aa3c5a787c
commit 99ea99b386
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 118 additions and 1 deletions

View File

@ -15860,7 +15860,11 @@ namespace ts {
}
function isSingletonTupleType(node: TypeNode) {
return isTupleTypeNode(node) && length(node.elements) === 1 && !isOptionalTypeNode(node.elements[0]) && !isRestTypeNode(node.elements[0]);
return isTupleTypeNode(node) &&
length(node.elements) === 1 &&
!isOptionalTypeNode(node.elements[0]) &&
!isRestTypeNode(node.elements[0]) &&
!(isNamedTupleMember(node.elements[0]) && (node.elements[0].questionToken || node.elements[0].dotDotDotToken));
}
/**

View File

@ -0,0 +1,19 @@
//// [singletonLabeledTuple.ts]
type AliasOptional = [p?: number]
// literal type vs type alias
type Literal = [p?: number] extends [unknown] ? true : false // Expect `Literal` to be `false`
type Alias = AliasOptional extends [unknown] ? true : false // Expect `Alias` to be `false`
// labeled tuple vs normal tuple
type Labeled = [p?: number] extends [unknown] ? true : false // Expect `Labeled` to be `false`
type Normal = [number?] extends [unknown] ? true : false // Expect `Normal` to be `false`
type AliasRest = [...p: number[]];
type LiteralRest = [...p: number[]] extends [unknown] ? true : false; // Expect `LiteralRest` to be `false`
type AliasedRest = AliasRest extends [unknown] ? true : false; // Expect `AliasedRest` to be `false`
type NormalRest = [...number[]] extends [unknown] ? true : false; // Expect `NormalRest` to be `false`
//// [singletonLabeledTuple.js]

View File

@ -0,0 +1,33 @@
=== tests/cases/compiler/singletonLabeledTuple.ts ===
type AliasOptional = [p?: number]
>AliasOptional : Symbol(AliasOptional, Decl(singletonLabeledTuple.ts, 0, 0))
// literal type vs type alias
type Literal = [p?: number] extends [unknown] ? true : false // Expect `Literal` to be `false`
>Literal : Symbol(Literal, Decl(singletonLabeledTuple.ts, 0, 33))
type Alias = AliasOptional extends [unknown] ? true : false // Expect `Alias` to be `false`
>Alias : Symbol(Alias, Decl(singletonLabeledTuple.ts, 3, 60))
>AliasOptional : Symbol(AliasOptional, Decl(singletonLabeledTuple.ts, 0, 0))
// labeled tuple vs normal tuple
type Labeled = [p?: number] extends [unknown] ? true : false // Expect `Labeled` to be `false`
>Labeled : Symbol(Labeled, Decl(singletonLabeledTuple.ts, 4, 59))
type Normal = [number?] extends [unknown] ? true : false // Expect `Normal` to be `false`
>Normal : Symbol(Normal, Decl(singletonLabeledTuple.ts, 7, 60))
type AliasRest = [...p: number[]];
>AliasRest : Symbol(AliasRest, Decl(singletonLabeledTuple.ts, 8, 56))
type LiteralRest = [...p: number[]] extends [unknown] ? true : false; // Expect `LiteralRest` to be `false`
>LiteralRest : Symbol(LiteralRest, Decl(singletonLabeledTuple.ts, 11, 34))
type AliasedRest = AliasRest extends [unknown] ? true : false; // Expect `AliasedRest` to be `false`
>AliasedRest : Symbol(AliasedRest, Decl(singletonLabeledTuple.ts, 13, 69))
>AliasRest : Symbol(AliasRest, Decl(singletonLabeledTuple.ts, 8, 56))
type NormalRest = [...number[]] extends [unknown] ? true : false; // Expect `NormalRest` to be `false`
>NormalRest : Symbol(NormalRest, Decl(singletonLabeledTuple.ts, 14, 62))

View File

@ -0,0 +1,45 @@
=== tests/cases/compiler/singletonLabeledTuple.ts ===
type AliasOptional = [p?: number]
>AliasOptional : AliasOptional
// literal type vs type alias
type Literal = [p?: number] extends [unknown] ? true : false // Expect `Literal` to be `false`
>Literal : false
>true : true
>false : false
type Alias = AliasOptional extends [unknown] ? true : false // Expect `Alias` to be `false`
>Alias : false
>true : true
>false : false
// labeled tuple vs normal tuple
type Labeled = [p?: number] extends [unknown] ? true : false // Expect `Labeled` to be `false`
>Labeled : false
>true : true
>false : false
type Normal = [number?] extends [unknown] ? true : false // Expect `Normal` to be `false`
>Normal : false
>true : true
>false : false
type AliasRest = [...p: number[]];
>AliasRest : AliasRest
type LiteralRest = [...p: number[]] extends [unknown] ? true : false; // Expect `LiteralRest` to be `false`
>LiteralRest : false
>true : true
>false : false
type AliasedRest = AliasRest extends [unknown] ? true : false; // Expect `AliasedRest` to be `false`
>AliasedRest : false
>true : true
>false : false
type NormalRest = [...number[]] extends [unknown] ? true : false; // Expect `NormalRest` to be `false`
>NormalRest : false
>true : true
>false : false

View File

@ -0,0 +1,16 @@
type AliasOptional = [p?: number]
// literal type vs type alias
type Literal = [p?: number] extends [unknown] ? true : false // Expect `Literal` to be `false`
type Alias = AliasOptional extends [unknown] ? true : false // Expect `Alias` to be `false`
// labeled tuple vs normal tuple
type Labeled = [p?: number] extends [unknown] ? true : false // Expect `Labeled` to be `false`
type Normal = [number?] extends [unknown] ? true : false // Expect `Normal` to be `false`
type AliasRest = [...p: number[]];
type LiteralRest = [...p: number[]] extends [unknown] ? true : false; // Expect `LiteralRest` to be `false`
type AliasedRest = AliasRest extends [unknown] ? true : false; // Expect `AliasedRest` to be `false`
type NormalRest = [...number[]] extends [unknown] ? true : false; // Expect `NormalRest` to be `false`