mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-07-07 18:25:51 -05:00
feedback from pr
This commit is contained in:
@@ -4732,12 +4732,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function cloneTypePredicate(predicate: TypePredicate, mapper: TypeMapper): ThisTypePredicate | IdentifierTypePredicate {
|
||||
if (predicate.kind === TypePredicateKind.Identifier) {
|
||||
const identifierPredicate = predicate as IdentifierTypePredicate;
|
||||
if (isIdentifierTypePredicate(predicate)) {
|
||||
return {
|
||||
kind: TypePredicateKind.Identifier,
|
||||
parameterName: identifierPredicate.parameterName,
|
||||
parameterIndex: identifierPredicate.parameterIndex,
|
||||
parameterName: predicate.parameterName,
|
||||
parameterIndex: predicate.parameterIndex,
|
||||
type: instantiateType(predicate.type, mapper)
|
||||
} as IdentifierTypePredicate;
|
||||
}
|
||||
@@ -4751,18 +4750,14 @@ namespace ts {
|
||||
|
||||
function instantiateSignature(signature: Signature, mapper: TypeMapper, eraseTypeParameters?: boolean): Signature {
|
||||
let freshTypeParameters: TypeParameter[];
|
||||
let freshTypePredicate: ThisTypePredicate | IdentifierTypePredicate;
|
||||
if (signature.typeParameters && !eraseTypeParameters) {
|
||||
freshTypeParameters = instantiateList(signature.typeParameters, mapper, instantiateTypeParameter);
|
||||
mapper = combineTypeMappers(createTypeMapper(signature.typeParameters, freshTypeParameters), mapper);
|
||||
}
|
||||
if (signature.typePredicate) {
|
||||
freshTypePredicate = cloneTypePredicate(signature.typePredicate, mapper);
|
||||
}
|
||||
const result = createSignature(signature.declaration, freshTypeParameters,
|
||||
instantiateList(signature.parameters, mapper, instantiateSymbol),
|
||||
instantiateType(signature.resolvedReturnType, mapper),
|
||||
freshTypePredicate,
|
||||
signature.typePredicate && cloneTypePredicate(signature.typePredicate, mapper),
|
||||
signature.minArgumentCount, signature.hasRestParameter, signature.hasStringLiterals);
|
||||
result.target = signature;
|
||||
result.mapper = mapper;
|
||||
@@ -6752,7 +6747,7 @@ namespace ts {
|
||||
const predicate = signature.typePredicate;
|
||||
if (isIdentifierTypePredicate(predicate)) {
|
||||
if (expr.arguments[predicate.parameterIndex] &&
|
||||
getSymbolAtLocation(expr.arguments[predicate.parameterIndex]) === symbol) {
|
||||
getSymbolAtTypePredicatePosition(expr.arguments[predicate.parameterIndex]) === symbol) {
|
||||
return getNarrowedType(type, predicate.type, assumeTrue);
|
||||
}
|
||||
}
|
||||
@@ -6762,18 +6757,28 @@ namespace ts {
|
||||
if (expression.kind === SyntaxKind.ElementAccessExpression || expression.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
const accessExpression = expression as ElementAccessExpression | PropertyAccessExpression;
|
||||
const possibleIdentifier = skipParenthesizedNodes(accessExpression.expression);
|
||||
if (possibleIdentifier.kind === SyntaxKind.Identifier && getSymbolAtLocation(possibleIdentifier) === symbol) {
|
||||
if (possibleIdentifier.kind === SyntaxKind.Identifier && getSymbolAtTypePredicatePosition(possibleIdentifier) === symbol) {
|
||||
return getNarrowedType(type, predicate.type, assumeTrue);
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function skipParenthesizedNodes(expression: Expression): Expression {
|
||||
while (expression.kind === SyntaxKind.ParenthesizedExpression) {
|
||||
expression = (expression as ParenthesizedExpression).expression;
|
||||
}
|
||||
return expression;
|
||||
function skipParenthesizedNodes(expression: Expression): Expression {
|
||||
while (expression.kind === SyntaxKind.ParenthesizedExpression) {
|
||||
expression = (expression as ParenthesizedExpression).expression;
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
function getSymbolAtTypePredicatePosition(expr: Expression): Symbol {
|
||||
expr = skipParenthesizedNodes(expr);
|
||||
switch (expr.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.QualifiedName:
|
||||
return getSymbolOfEntityNameOrPropertyAccessExpression(expr as Node as (EntityName | PropertyAccessExpression));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1632,7 +1632,7 @@
|
||||
"category": "Error",
|
||||
"code": 2517
|
||||
},
|
||||
"A this based type guard is not assignable to a parameter based type guard": {
|
||||
"A 'this'-based type guard is not assignable to a parameter-based type guard": {
|
||||
"category": "Error",
|
||||
"code": 2518
|
||||
},
|
||||
|
||||
@@ -132,7 +132,8 @@ a.isFollower = mimic.isFollower;
|
||||
if (mimic.isFollower()) {
|
||||
mimic.follow();
|
||||
mimic.isFollower = a.isFollower;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [typeGuardFunctionOfFormThis.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
@@ -279,3 +280,58 @@ if (mimic.isFollower()) {
|
||||
mimic.follow();
|
||||
mimic.isFollower = a.isFollower;
|
||||
}
|
||||
|
||||
|
||||
//// [typeGuardFunctionOfFormThis.d.ts]
|
||||
declare class RoyalGuard {
|
||||
isLeader(): this is LeadGuard;
|
||||
isFollower(): this is FollowerGuard;
|
||||
}
|
||||
declare class LeadGuard extends RoyalGuard {
|
||||
lead(): void;
|
||||
}
|
||||
declare class FollowerGuard extends RoyalGuard {
|
||||
follow(): void;
|
||||
}
|
||||
declare let a: RoyalGuard;
|
||||
interface GuardInterface extends RoyalGuard {
|
||||
}
|
||||
declare let b: GuardInterface;
|
||||
declare var holder2: {
|
||||
a: RoyalGuard;
|
||||
};
|
||||
declare class ArrowGuard {
|
||||
isElite: () => this is ArrowElite;
|
||||
isMedic: () => this is ArrowMedic;
|
||||
}
|
||||
declare class ArrowElite extends ArrowGuard {
|
||||
defend(): void;
|
||||
}
|
||||
declare class ArrowMedic extends ArrowGuard {
|
||||
heal(): void;
|
||||
}
|
||||
declare let guard: ArrowGuard;
|
||||
interface Supplies {
|
||||
spoiled: boolean;
|
||||
}
|
||||
interface Sundries {
|
||||
broken: boolean;
|
||||
}
|
||||
interface Crate<T> {
|
||||
contents: T;
|
||||
volume: number;
|
||||
isSupplies(): this is Crate<Supplies>;
|
||||
isSundries(): this is Crate<Sundries>;
|
||||
}
|
||||
declare let crate: Crate<{}>;
|
||||
declare class MimicGuard {
|
||||
isLeader(): this is MimicLeader;
|
||||
isFollower(): this is MimicFollower;
|
||||
}
|
||||
declare class MimicLeader extends MimicGuard {
|
||||
lead(): void;
|
||||
}
|
||||
declare class MimicFollower extends MimicGuard {
|
||||
follow(): void;
|
||||
}
|
||||
declare let mimic: MimicGuard;
|
||||
|
||||
@@ -369,3 +369,4 @@ if (mimic.isFollower()) {
|
||||
>a : Symbol(a, Decl(typeGuardFunctionOfFormThis.ts, 17, 3))
|
||||
>isFollower : Symbol(RoyalGuard.isFollower, Decl(typeGuardFunctionOfFormThis.ts, 3, 5))
|
||||
}
|
||||
|
||||
|
||||
@@ -425,3 +425,4 @@ if (mimic.isFollower()) {
|
||||
>a : RoyalGuard
|
||||
>isFollower : () => this is FollowerGuard
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,11 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors.ts(27,1): error TS2322: Type '() => this is FollowerGuard' is not assignable to type '() => this is LeadGuard'.
|
||||
Type 'FollowerGuard' is not assignable to type 'LeadGuard'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors.ts(29,32): error TS2526: A 'this' type is available only in a non-static member of a class or interface.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors.ts(55,7): error TS2339: Property 'follow' does not exist on type 'RoyalGuard'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors.ts(58,7): error TS2339: Property 'lead' does not exist on type 'RoyalGuard'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors.ts (5 errors) ====
|
||||
==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors.ts (7 errors) ====
|
||||
class RoyalGuard {
|
||||
isLeader(): this is LeadGuard {
|
||||
return this instanceof LeadGuard;
|
||||
@@ -73,4 +75,17 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors
|
||||
else {
|
||||
c;
|
||||
holder;
|
||||
}
|
||||
|
||||
let detached = a.isFollower;
|
||||
|
||||
if (detached()) {
|
||||
a.follow();
|
||||
~~~~~~
|
||||
!!! error TS2339: Property 'follow' does not exist on type 'RoyalGuard'.
|
||||
}
|
||||
else {
|
||||
a.lead();
|
||||
~~~~
|
||||
!!! error TS2339: Property 'lead' does not exist on type 'RoyalGuard'.
|
||||
}
|
||||
@@ -48,6 +48,15 @@ if (holder.invalidGuard(c)) {
|
||||
else {
|
||||
c;
|
||||
holder;
|
||||
}
|
||||
|
||||
let detached = a.isFollower;
|
||||
|
||||
if (detached()) {
|
||||
a.follow();
|
||||
}
|
||||
else {
|
||||
a.lead();
|
||||
}
|
||||
|
||||
//// [typeGuardFunctionOfFormThisErrors.js]
|
||||
@@ -111,3 +120,33 @@ else {
|
||||
c;
|
||||
holder;
|
||||
}
|
||||
var detached = a.isFollower;
|
||||
if (detached()) {
|
||||
a.follow();
|
||||
}
|
||||
else {
|
||||
a.lead();
|
||||
}
|
||||
|
||||
|
||||
//// [typeGuardFunctionOfFormThisErrors.d.ts]
|
||||
declare class RoyalGuard {
|
||||
isLeader(): this is LeadGuard;
|
||||
isFollower(): this is FollowerGuard;
|
||||
}
|
||||
declare class LeadGuard extends RoyalGuard {
|
||||
lead(): void;
|
||||
}
|
||||
declare class FollowerGuard extends RoyalGuard {
|
||||
follow(): void;
|
||||
}
|
||||
interface GuardInterface extends RoyalGuard {
|
||||
}
|
||||
declare let a: RoyalGuard;
|
||||
declare let b: GuardInterface;
|
||||
declare function invalidGuard(c: any): this is number;
|
||||
declare let c: number | number[];
|
||||
declare let holder: {
|
||||
invalidGuard: (c: any) => this is number;
|
||||
};
|
||||
declare let detached: () => this is FollowerGuard;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @declaration: true
|
||||
class RoyalGuard {
|
||||
isLeader(): this is LeadGuard {
|
||||
return this instanceof LeadGuard;
|
||||
@@ -131,4 +132,4 @@ a.isFollower = mimic.isFollower;
|
||||
if (mimic.isFollower()) {
|
||||
mimic.follow();
|
||||
mimic.isFollower = a.isFollower;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @declaration: true
|
||||
class RoyalGuard {
|
||||
isLeader(): this is LeadGuard {
|
||||
return this instanceof LeadGuard;
|
||||
@@ -47,4 +48,13 @@ if (holder.invalidGuard(c)) {
|
||||
else {
|
||||
c;
|
||||
holder;
|
||||
}
|
||||
|
||||
let detached = a.isFollower;
|
||||
|
||||
if (detached()) {
|
||||
a.follow();
|
||||
}
|
||||
else {
|
||||
a.lead();
|
||||
}
|
||||
Reference in New Issue
Block a user