mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into isInMultiLineComment
This commit is contained in:
+110
-30
@@ -5788,8 +5788,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isGenericMappedType(type: Type) {
|
||||
return getObjectFlags(type) & ObjectFlags.Mapped &&
|
||||
maybeTypeOfKind(getConstraintTypeFromMappedType(<MappedType>type), TypeFlags.TypeVariable | TypeFlags.Index);
|
||||
return getObjectFlags(type) & ObjectFlags.Mapped && isGenericIndexType(getConstraintTypeFromMappedType(<MappedType>type));
|
||||
}
|
||||
|
||||
function resolveStructuredTypeMembers(type: StructuredType): ResolvedType {
|
||||
@@ -5901,6 +5900,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getConstraintOfIndexedAccess(type: IndexedAccessType) {
|
||||
const transformed = getTransformedIndexedAccessType(type);
|
||||
if (transformed) {
|
||||
return transformed;
|
||||
}
|
||||
const baseObjectType = getBaseConstraintOfType(type.objectType);
|
||||
const baseIndexType = getBaseConstraintOfType(type.indexType);
|
||||
return baseObjectType || baseIndexType ? getIndexedAccessType(baseObjectType || type.objectType, baseIndexType || type.indexType) : undefined;
|
||||
@@ -5972,11 +5975,18 @@ namespace ts {
|
||||
return stringType;
|
||||
}
|
||||
if (t.flags & TypeFlags.IndexedAccess) {
|
||||
const transformed = getTransformedIndexedAccessType(<IndexedAccessType>t);
|
||||
if (transformed) {
|
||||
return getBaseConstraint(transformed);
|
||||
}
|
||||
const baseObjectType = getBaseConstraint((<IndexedAccessType>t).objectType);
|
||||
const baseIndexType = getBaseConstraint((<IndexedAccessType>t).indexType);
|
||||
const baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined;
|
||||
return baseIndexedAccess && baseIndexedAccess !== unknownType ? getBaseConstraint(baseIndexedAccess) : undefined;
|
||||
}
|
||||
if (isGenericMappedType(t)) {
|
||||
return emptyObjectType;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
@@ -7604,26 +7614,73 @@ namespace ts {
|
||||
return instantiateType(getTemplateTypeFromMappedType(type), templateMapper);
|
||||
}
|
||||
|
||||
function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode) {
|
||||
// If the index type is generic, if the object type is generic and doesn't originate in an expression,
|
||||
// or if the object type is a mapped type with a generic constraint, we are performing a higher-order
|
||||
// index access where we cannot meaningfully access the properties of the object type. Note that for a
|
||||
// generic T and a non-generic K, we eagerly resolve T[K] if it originates in an expression. This is to
|
||||
// preserve backwards compatibility. For example, an element access 'this["foo"]' has always been resolved
|
||||
// eagerly using the constraint type of 'this' at the given location.
|
||||
if (maybeTypeOfKind(indexType, TypeFlags.TypeVariable | TypeFlags.Index) ||
|
||||
maybeTypeOfKind(objectType, TypeFlags.TypeVariable) && !(accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression) ||
|
||||
isGenericMappedType(objectType)) {
|
||||
function isGenericObjectType(type: Type): boolean {
|
||||
return type.flags & TypeFlags.TypeVariable ? true :
|
||||
getObjectFlags(type) & ObjectFlags.Mapped ? isGenericIndexType(getConstraintTypeFromMappedType(<MappedType>type)) :
|
||||
type.flags & TypeFlags.UnionOrIntersection ? forEach((<UnionOrIntersectionType>type).types, isGenericObjectType) :
|
||||
false;
|
||||
}
|
||||
|
||||
function isGenericIndexType(type: Type): boolean {
|
||||
return type.flags & (TypeFlags.TypeVariable | TypeFlags.Index) ? true :
|
||||
type.flags & TypeFlags.UnionOrIntersection ? forEach((<UnionOrIntersectionType>type).types, isGenericIndexType) :
|
||||
false;
|
||||
}
|
||||
|
||||
// Return true if the given type is a non-generic object type with a string index signature and no
|
||||
// other members.
|
||||
function isStringIndexOnlyType(type: Type) {
|
||||
if (type.flags & TypeFlags.Object && !isGenericMappedType(type)) {
|
||||
const t = resolveStructuredTypeMembers(<ObjectType>type);
|
||||
return t.properties.length === 0 &&
|
||||
t.callSignatures.length === 0 && t.constructSignatures.length === 0 &&
|
||||
t.stringIndexInfo && !t.numberIndexInfo;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or
|
||||
// more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a
|
||||
// transformed type of the form '(U & V)[K] | D'. This allows us to properly reason about higher order indexed
|
||||
// access types with default property values as expressed by D.
|
||||
function getTransformedIndexedAccessType(type: IndexedAccessType): Type {
|
||||
const objectType = type.objectType;
|
||||
if (objectType.flags & TypeFlags.Intersection && isGenericObjectType(objectType) && some((<IntersectionType>objectType).types, isStringIndexOnlyType)) {
|
||||
const regularTypes: Type[] = [];
|
||||
const stringIndexTypes: Type[] = [];
|
||||
for (const t of (<IntersectionType>objectType).types) {
|
||||
if (isStringIndexOnlyType(t)) {
|
||||
stringIndexTypes.push(getIndexTypeOfType(t, IndexKind.String));
|
||||
}
|
||||
else {
|
||||
regularTypes.push(t);
|
||||
}
|
||||
}
|
||||
return getUnionType([
|
||||
getIndexedAccessType(getIntersectionType(regularTypes), type.indexType),
|
||||
getIntersectionType(stringIndexTypes)
|
||||
]);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode): Type {
|
||||
// If the object type is a mapped type { [P in K]: E }, where K is generic, we instantiate E using a mapper
|
||||
// that substitutes the index type for P. For example, for an index access { [P in K]: Box<T[P]> }[X], we
|
||||
// construct the type Box<T[X]>.
|
||||
if (isGenericMappedType(objectType)) {
|
||||
return getIndexedAccessForMappedType(<MappedType>objectType, indexType, accessNode);
|
||||
}
|
||||
// Otherwise, if the index type is generic, or if the object type is generic and doesn't originate in an
|
||||
// expression, we are performing a higher-order index access where we cannot meaningfully access the properties
|
||||
// of the object type. Note that for a generic T and a non-generic K, we eagerly resolve T[K] if it originates
|
||||
// in an expression. This is to preserve backwards compatibility. For example, an element access 'this["foo"]'
|
||||
// has always been resolved eagerly using the constraint type of 'this' at the given location.
|
||||
if (isGenericIndexType(indexType) || !(accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression) && isGenericObjectType(objectType)) {
|
||||
if (objectType.flags & TypeFlags.Any) {
|
||||
return objectType;
|
||||
}
|
||||
// If the object type is a mapped type { [P in K]: E }, we instantiate E using a mapper that substitutes
|
||||
// the index type for P. For example, for an index access { [P in K]: Box<T[P]> }[X], we construct the
|
||||
// type Box<T[X]>.
|
||||
if (isGenericMappedType(objectType)) {
|
||||
return getIndexedAccessForMappedType(<MappedType>objectType, indexType, accessNode);
|
||||
}
|
||||
// Otherwise we defer the operation by creating an indexed access type.
|
||||
// Defer the operation by creating an indexed access type.
|
||||
const id = objectType.id + "," + indexType.id;
|
||||
let type = indexedAccessTypes.get(id);
|
||||
if (!type) {
|
||||
@@ -8017,7 +8074,7 @@ namespace ts {
|
||||
|
||||
function cloneTypeMapper(mapper: TypeMapper): TypeMapper {
|
||||
return mapper && isInferenceContext(mapper) ?
|
||||
createInferenceContext(mapper.signature, mapper.flags | InferenceFlags.NoDefault, mapper.inferences) :
|
||||
createInferenceContext(mapper.signature, mapper.flags | InferenceFlags.NoDefault, mapper.compareTypes, mapper.inferences) :
|
||||
mapper;
|
||||
}
|
||||
|
||||
@@ -8458,7 +8515,7 @@ namespace ts {
|
||||
ignoreReturnTypes: boolean,
|
||||
reportErrors: boolean,
|
||||
errorReporter: ErrorReporter,
|
||||
compareTypes: (s: Type, t: Type, reportErrors?: boolean) => Ternary): Ternary {
|
||||
compareTypes: TypeComparer): Ternary {
|
||||
// TODO (drosen): De-duplicate code between related functions.
|
||||
if (source === target) {
|
||||
return Ternary.True;
|
||||
@@ -8468,7 +8525,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (source.typeParameters) {
|
||||
source = instantiateSignatureInContextOf(source, target);
|
||||
source = instantiateSignatureInContextOf(source, target, /*contextualMapper*/ undefined, compareTypes);
|
||||
}
|
||||
|
||||
let result = Ternary.True;
|
||||
@@ -9614,6 +9671,11 @@ namespace ts {
|
||||
if (sourceInfo) {
|
||||
return indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors);
|
||||
}
|
||||
if (isGenericMappedType(source)) {
|
||||
// A generic mapped type { [P in K]: T } is related to an index signature { [x: string]: U }
|
||||
// if T is related to U.
|
||||
return kind === IndexKind.String && isRelatedTo(getTemplateTypeFromMappedType(<MappedType>source), targetInfo.type, reportErrors);
|
||||
}
|
||||
if (isObjectLiteralType(source)) {
|
||||
let related = Ternary.True;
|
||||
if (kind === IndexKind.String) {
|
||||
@@ -10216,13 +10278,14 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createInferenceContext(signature: Signature, flags: InferenceFlags, baseInferences?: InferenceInfo[]): InferenceContext {
|
||||
function createInferenceContext(signature: Signature, flags: InferenceFlags, compareTypes?: TypeComparer, baseInferences?: InferenceInfo[]): InferenceContext {
|
||||
const inferences = baseInferences ? map(baseInferences, cloneInferenceInfo) : map(signature.typeParameters, createInferenceInfo);
|
||||
const context = mapper as InferenceContext;
|
||||
context.mappedTypes = signature.typeParameters;
|
||||
context.signature = signature;
|
||||
context.inferences = inferences;
|
||||
context.flags = flags;
|
||||
context.compareTypes = compareTypes || compareTypesAssignable;
|
||||
return context;
|
||||
|
||||
function mapper(t: Type): Type {
|
||||
@@ -10325,6 +10388,19 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isPossiblyAssignableTo(source: Type, target: Type) {
|
||||
const properties = getPropertiesOfObjectType(target);
|
||||
for (const targetProp of properties) {
|
||||
if (!(targetProp.flags & (SymbolFlags.Optional | SymbolFlags.Prototype))) {
|
||||
const sourceProp = getPropertyOfObjectType(source, targetProp.escapedName);
|
||||
if (!sourceProp) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0) {
|
||||
let symbolStack: Symbol[];
|
||||
let visited: Map<boolean>;
|
||||
@@ -10518,10 +10594,14 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
}
|
||||
inferFromProperties(source, target);
|
||||
inferFromSignatures(source, target, SignatureKind.Call);
|
||||
inferFromSignatures(source, target, SignatureKind.Construct);
|
||||
inferFromIndexTypes(source, target);
|
||||
// Infer from the members of source and target only if the two types are possibly related. We check
|
||||
// in both directions because we may be inferring for a co-variant or a contra-variant position.
|
||||
if (isPossiblyAssignableTo(source, target) || isPossiblyAssignableTo(target, source)) {
|
||||
inferFromProperties(source, target);
|
||||
inferFromSignatures(source, target, SignatureKind.Call);
|
||||
inferFromSignatures(source, target, SignatureKind.Construct);
|
||||
inferFromIndexTypes(source, target);
|
||||
}
|
||||
}
|
||||
|
||||
function inferFromProperties(source: Type, target: Type) {
|
||||
@@ -10653,7 +10733,7 @@ namespace ts {
|
||||
const constraint = getConstraintOfTypeParameter(context.signature.typeParameters[index]);
|
||||
if (constraint) {
|
||||
const instantiatedConstraint = instantiateType(constraint, context);
|
||||
if (!isTypeAssignableTo(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
|
||||
if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
|
||||
inference.inferredType = inferredType = instantiatedConstraint;
|
||||
}
|
||||
}
|
||||
@@ -15054,8 +15134,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
|
||||
function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper?: TypeMapper): Signature {
|
||||
const context = createInferenceContext(signature, InferenceFlags.InferUnionTypes);
|
||||
function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper?: TypeMapper, compareTypes?: TypeComparer): Signature {
|
||||
const context = createInferenceContext(signature, InferenceFlags.InferUnionTypes, compareTypes);
|
||||
forEachMatchingParameterType(contextualSignature, signature, (source, target) => {
|
||||
// Type parameters from outer context referenced by source type are fixed by instantiation of the source type
|
||||
inferTypes(context.inferences, instantiateType(source, contextualMapper || identityMapper), target);
|
||||
|
||||
@@ -11,20 +11,6 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
/**
|
||||
* Ternary values are defined such that
|
||||
* x & y is False if either x or y is False.
|
||||
* x & y is Maybe if either x or y is Maybe, but neither x or y is False.
|
||||
* x & y is True if both x and y are True.
|
||||
* x | y is False if both x and y are False.
|
||||
* x | y is Maybe if either x or y is Maybe, but neither x or y is True.
|
||||
* x | y is True if either x or y is True.
|
||||
*/
|
||||
export const enum Ternary {
|
||||
False = 0,
|
||||
Maybe = 1,
|
||||
True = -1
|
||||
}
|
||||
|
||||
// More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times.
|
||||
export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "accent" }) : undefined;
|
||||
|
||||
@@ -1346,7 +1346,9 @@ namespace ts {
|
||||
|
||||
emitExpression(node.left);
|
||||
increaseIndentIf(indentBeforeOperator, isCommaOperator ? " " : undefined);
|
||||
emitLeadingCommentsOfPosition(node.operatorToken.pos);
|
||||
writeTokenNode(node.operatorToken);
|
||||
emitTrailingCommentsOfPosition(node.operatorToken.end);
|
||||
increaseIndentIf(indentAfterOperator, " ");
|
||||
emitExpression(node.right);
|
||||
decreaseIndentIf(indentBeforeOperator, indentAfterOperator);
|
||||
|
||||
+27
-7
@@ -2061,7 +2061,7 @@ namespace ts {
|
||||
return <TemplateMiddle | TemplateTail>fragment;
|
||||
}
|
||||
|
||||
function parseLiteralLikeNode(kind: SyntaxKind): LiteralLikeNode {
|
||||
function parseLiteralLikeNode(kind: SyntaxKind): LiteralExpression | LiteralLikeNode {
|
||||
const node = <LiteralExpression>createNode(kind);
|
||||
const text = scanner.getTokenValue();
|
||||
node.text = text;
|
||||
@@ -2611,11 +2611,31 @@ namespace ts {
|
||||
return token() === SyntaxKind.DotToken ? undefined : node;
|
||||
}
|
||||
|
||||
function parseLiteralTypeNode(): LiteralTypeNode {
|
||||
const node = <LiteralTypeNode>createNode(SyntaxKind.LiteralType);
|
||||
node.literal = parseSimpleUnaryExpression();
|
||||
finishNode(node);
|
||||
return node;
|
||||
function parseLiteralTypeNode(negative?: boolean): LiteralTypeNode {
|
||||
const node = createNode(SyntaxKind.LiteralType) as LiteralTypeNode;
|
||||
let unaryMinusExpression: PrefixUnaryExpression;
|
||||
if (negative) {
|
||||
unaryMinusExpression = createNode(SyntaxKind.PrefixUnaryExpression) as PrefixUnaryExpression;
|
||||
unaryMinusExpression.operator = SyntaxKind.MinusToken;
|
||||
nextToken();
|
||||
}
|
||||
let expression: UnaryExpression;
|
||||
switch (token()) {
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
expression = parseLiteralLikeNode(token()) as LiteralExpression;
|
||||
break;
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
expression = parseTokenNode();
|
||||
}
|
||||
if (negative) {
|
||||
unaryMinusExpression.operand = expression;
|
||||
finishNode(unaryMinusExpression);
|
||||
expression = unaryMinusExpression;
|
||||
}
|
||||
node.literal = expression;
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function nextTokenIsNumericLiteral() {
|
||||
@@ -2650,7 +2670,7 @@ namespace ts {
|
||||
case SyntaxKind.FalseKeyword:
|
||||
return parseLiteralTypeNode();
|
||||
case SyntaxKind.MinusToken:
|
||||
return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode() : parseTypeReference();
|
||||
return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference();
|
||||
case SyntaxKind.VoidKeyword:
|
||||
case SyntaxKind.NullKeyword:
|
||||
return parseTokenNode<TypeNode>();
|
||||
|
||||
@@ -3425,11 +3425,29 @@ namespace ts {
|
||||
AnyDefault = 1 << 2, // Infer anyType for no inferences (otherwise emptyObjectType)
|
||||
}
|
||||
|
||||
/**
|
||||
* Ternary values are defined such that
|
||||
* x & y is False if either x or y is False.
|
||||
* x & y is Maybe if either x or y is Maybe, but neither x or y is False.
|
||||
* x & y is True if both x and y are True.
|
||||
* x | y is False if both x and y are False.
|
||||
* x | y is Maybe if either x or y is Maybe, but neither x or y is True.
|
||||
* x | y is True if either x or y is True.
|
||||
*/
|
||||
export const enum Ternary {
|
||||
False = 0,
|
||||
Maybe = 1,
|
||||
True = -1
|
||||
}
|
||||
|
||||
export type TypeComparer = (s: Type, t: Type, reportErrors?: boolean) => Ternary;
|
||||
|
||||
/* @internal */
|
||||
export interface InferenceContext extends TypeMapper {
|
||||
signature: Signature; // Generic signature for which inferences are made
|
||||
inferences: InferenceInfo[]; // Inferences made for each type parameter
|
||||
flags: InferenceFlags; // Inference flags
|
||||
compareTypes: TypeComparer; // Type comparer function
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
||||
@@ -1000,7 +1000,7 @@ namespace ts.Completions {
|
||||
const typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
|
||||
if (!typeForObject) return false;
|
||||
// In a binding pattern, get only known properties. Everywhere else we will get all possible properties.
|
||||
typeMembers = typeChecker.getPropertiesOfType(typeForObject);
|
||||
typeMembers = typeChecker.getPropertiesOfType(typeForObject).filter((symbol) => !(getDeclarationModifierFlagsFromSymbol(symbol) & ModifierFlags.NonPublicAccessibilityModifier));
|
||||
existingMembers = (<ObjectBindingPattern>objectLikeContainer).elements;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
//// [commentOnBinaryOperator1.ts]
|
||||
var a = 'some'
|
||||
// comment
|
||||
+ 'text';
|
||||
|
||||
var b = 'some'
|
||||
/* comment */
|
||||
+ 'text';
|
||||
|
||||
var c = 'some'
|
||||
/* comment */
|
||||
+ /*comment1*/
|
||||
'text';
|
||||
|
||||
//// [commentOnBinaryOperator1.js]
|
||||
var a = 'some'
|
||||
// comment
|
||||
+ 'text';
|
||||
var b = 'some'
|
||||
/* comment */
|
||||
+ 'text';
|
||||
var c = 'some'
|
||||
/* comment */
|
||||
+/*comment1*/
|
||||
'text';
|
||||
@@ -0,0 +1,19 @@
|
||||
=== tests/cases/compiler/commentOnBinaryOperator1.ts ===
|
||||
var a = 'some'
|
||||
>a : Symbol(a, Decl(commentOnBinaryOperator1.ts, 0, 3))
|
||||
|
||||
// comment
|
||||
+ 'text';
|
||||
|
||||
var b = 'some'
|
||||
>b : Symbol(b, Decl(commentOnBinaryOperator1.ts, 4, 3))
|
||||
|
||||
/* comment */
|
||||
+ 'text';
|
||||
|
||||
var c = 'some'
|
||||
>c : Symbol(c, Decl(commentOnBinaryOperator1.ts, 8, 3))
|
||||
|
||||
/* comment */
|
||||
+ /*comment1*/
|
||||
'text';
|
||||
@@ -0,0 +1,29 @@
|
||||
=== tests/cases/compiler/commentOnBinaryOperator1.ts ===
|
||||
var a = 'some'
|
||||
>a : string
|
||||
>'some' // comment + 'text' : string
|
||||
>'some' : "some"
|
||||
|
||||
// comment
|
||||
+ 'text';
|
||||
>'text' : "text"
|
||||
|
||||
var b = 'some'
|
||||
>b : string
|
||||
>'some' /* comment */ + 'text' : string
|
||||
>'some' : "some"
|
||||
|
||||
/* comment */
|
||||
+ 'text';
|
||||
>'text' : "text"
|
||||
|
||||
var c = 'some'
|
||||
>c : string
|
||||
>'some' /* comment */ + /*comment1*/ 'text' : string
|
||||
>'some' : "some"
|
||||
|
||||
/* comment */
|
||||
+ /*comment1*/
|
||||
'text';
|
||||
>'text' : "text"
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
//// [commentOnBinaryOperator2.ts]
|
||||
var a = 'some'
|
||||
// comment
|
||||
+ 'text';
|
||||
|
||||
var b = 'some'
|
||||
/* comment */
|
||||
+ 'text';
|
||||
|
||||
var c = 'some'
|
||||
/* comment */
|
||||
+ /*comment1*/
|
||||
'text';
|
||||
|
||||
//// [commentOnBinaryOperator2.js]
|
||||
var a = 'some'
|
||||
+ 'text';
|
||||
var b = 'some'
|
||||
+ 'text';
|
||||
var c = 'some'
|
||||
+
|
||||
'text';
|
||||
@@ -0,0 +1,19 @@
|
||||
=== tests/cases/compiler/commentOnBinaryOperator2.ts ===
|
||||
var a = 'some'
|
||||
>a : Symbol(a, Decl(commentOnBinaryOperator2.ts, 0, 3))
|
||||
|
||||
// comment
|
||||
+ 'text';
|
||||
|
||||
var b = 'some'
|
||||
>b : Symbol(b, Decl(commentOnBinaryOperator2.ts, 4, 3))
|
||||
|
||||
/* comment */
|
||||
+ 'text';
|
||||
|
||||
var c = 'some'
|
||||
>c : Symbol(c, Decl(commentOnBinaryOperator2.ts, 8, 3))
|
||||
|
||||
/* comment */
|
||||
+ /*comment1*/
|
||||
'text';
|
||||
@@ -0,0 +1,29 @@
|
||||
=== tests/cases/compiler/commentOnBinaryOperator2.ts ===
|
||||
var a = 'some'
|
||||
>a : string
|
||||
>'some' // comment + 'text' : string
|
||||
>'some' : "some"
|
||||
|
||||
// comment
|
||||
+ 'text';
|
||||
>'text' : "text"
|
||||
|
||||
var b = 'some'
|
||||
>b : string
|
||||
>'some' /* comment */ + 'text' : string
|
||||
>'some' : "some"
|
||||
|
||||
/* comment */
|
||||
+ 'text';
|
||||
>'text' : "text"
|
||||
|
||||
var c = 'some'
|
||||
>c : string
|
||||
>'some' /* comment */ + /*comment1*/ 'text' : string
|
||||
>'some' : "some"
|
||||
|
||||
/* comment */
|
||||
+ /*comment1*/
|
||||
'text';
|
||||
>'text' : "text"
|
||||
|
||||
@@ -14,7 +14,7 @@ foo(
|
||||
function foo(/*c1*/ x, /*d1*/ y, /*e1*/ w) { }
|
||||
var a, b;
|
||||
foo(/*c2*/ 1, /*d2*/ 1 + 2, /*e1*/ a + b);
|
||||
foo(/*c3*/ function () { }, /*d2*/ function () { }, /*e2*/ a + b);
|
||||
foo(/*c3*/ function () { }, /*d2*/ function () { }, /*e2*/ a +/*e3*/ b);
|
||||
foo(/*c3*/ function () { }, /*d3*/ function () { }, /*e3*/ (a + b));
|
||||
foo(
|
||||
/*c4*/ function () { },
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
//// [deferredLookupTypeResolution.ts]
|
||||
// Repro from #17456
|
||||
|
||||
type StringContains<S extends string, L extends string> = (
|
||||
{ [K in S]: 'true' } &
|
||||
{ [key: string]: 'false' }
|
||||
)[L]
|
||||
|
||||
type ObjectHasKey<O, L extends string> = StringContains<keyof O, L>
|
||||
|
||||
type First<T> = ObjectHasKey<T, '0'>; // Should be deferred
|
||||
|
||||
type T1 = ObjectHasKey<{ a: string }, 'a'>; // 'true'
|
||||
type T2 = ObjectHasKey<{ a: string }, 'b'>; // 'false'
|
||||
|
||||
// Verify that mapped type isn't eagerly resolved in type-to-string operation
|
||||
|
||||
declare function f1<A extends string, B extends string>(a: A, b: B): { [P in A | B]: any };
|
||||
|
||||
function f2<A extends string>(a: A) {
|
||||
return f1(a, 'x');
|
||||
}
|
||||
|
||||
function f3(x: 'a' | 'b') {
|
||||
return f2(x);
|
||||
}
|
||||
|
||||
|
||||
//// [deferredLookupTypeResolution.js]
|
||||
"use strict";
|
||||
// Repro from #17456
|
||||
function f2(a) {
|
||||
return f1(a, 'x');
|
||||
}
|
||||
function f3(x) {
|
||||
return f2(x);
|
||||
}
|
||||
|
||||
|
||||
//// [deferredLookupTypeResolution.d.ts]
|
||||
declare type StringContains<S extends string, L extends string> = ({
|
||||
[K in S]: 'true';
|
||||
} & {
|
||||
[key: string]: 'false';
|
||||
})[L];
|
||||
declare type ObjectHasKey<O, L extends string> = StringContains<keyof O, L>;
|
||||
declare type First<T> = ObjectHasKey<T, '0'>;
|
||||
declare type T1 = ObjectHasKey<{
|
||||
a: string;
|
||||
}, 'a'>;
|
||||
declare type T2 = ObjectHasKey<{
|
||||
a: string;
|
||||
}, 'b'>;
|
||||
declare function f1<A extends string, B extends string>(a: A, b: B): {
|
||||
[P in A | B]: any;
|
||||
};
|
||||
declare function f2<A extends string>(a: A): {
|
||||
[P in A | "x"]: any;
|
||||
};
|
||||
declare function f3(x: 'a' | 'b'): {
|
||||
a: any;
|
||||
b: any;
|
||||
x: any;
|
||||
};
|
||||
@@ -0,0 +1,76 @@
|
||||
=== tests/cases/compiler/deferredLookupTypeResolution.ts ===
|
||||
// Repro from #17456
|
||||
|
||||
type StringContains<S extends string, L extends string> = (
|
||||
>StringContains : Symbol(StringContains, Decl(deferredLookupTypeResolution.ts, 0, 0))
|
||||
>S : Symbol(S, Decl(deferredLookupTypeResolution.ts, 2, 20))
|
||||
>L : Symbol(L, Decl(deferredLookupTypeResolution.ts, 2, 37))
|
||||
|
||||
{ [K in S]: 'true' } &
|
||||
>K : Symbol(K, Decl(deferredLookupTypeResolution.ts, 3, 7))
|
||||
>S : Symbol(S, Decl(deferredLookupTypeResolution.ts, 2, 20))
|
||||
|
||||
{ [key: string]: 'false' }
|
||||
>key : Symbol(key, Decl(deferredLookupTypeResolution.ts, 4, 7))
|
||||
|
||||
)[L]
|
||||
>L : Symbol(L, Decl(deferredLookupTypeResolution.ts, 2, 37))
|
||||
|
||||
type ObjectHasKey<O, L extends string> = StringContains<keyof O, L>
|
||||
>ObjectHasKey : Symbol(ObjectHasKey, Decl(deferredLookupTypeResolution.ts, 5, 6))
|
||||
>O : Symbol(O, Decl(deferredLookupTypeResolution.ts, 7, 18))
|
||||
>L : Symbol(L, Decl(deferredLookupTypeResolution.ts, 7, 20))
|
||||
>StringContains : Symbol(StringContains, Decl(deferredLookupTypeResolution.ts, 0, 0))
|
||||
>O : Symbol(O, Decl(deferredLookupTypeResolution.ts, 7, 18))
|
||||
>L : Symbol(L, Decl(deferredLookupTypeResolution.ts, 7, 20))
|
||||
|
||||
type First<T> = ObjectHasKey<T, '0'>; // Should be deferred
|
||||
>First : Symbol(First, Decl(deferredLookupTypeResolution.ts, 7, 67))
|
||||
>T : Symbol(T, Decl(deferredLookupTypeResolution.ts, 9, 11))
|
||||
>ObjectHasKey : Symbol(ObjectHasKey, Decl(deferredLookupTypeResolution.ts, 5, 6))
|
||||
>T : Symbol(T, Decl(deferredLookupTypeResolution.ts, 9, 11))
|
||||
|
||||
type T1 = ObjectHasKey<{ a: string }, 'a'>; // 'true'
|
||||
>T1 : Symbol(T1, Decl(deferredLookupTypeResolution.ts, 9, 37))
|
||||
>ObjectHasKey : Symbol(ObjectHasKey, Decl(deferredLookupTypeResolution.ts, 5, 6))
|
||||
>a : Symbol(a, Decl(deferredLookupTypeResolution.ts, 11, 24))
|
||||
|
||||
type T2 = ObjectHasKey<{ a: string }, 'b'>; // 'false'
|
||||
>T2 : Symbol(T2, Decl(deferredLookupTypeResolution.ts, 11, 43))
|
||||
>ObjectHasKey : Symbol(ObjectHasKey, Decl(deferredLookupTypeResolution.ts, 5, 6))
|
||||
>a : Symbol(a, Decl(deferredLookupTypeResolution.ts, 12, 24))
|
||||
|
||||
// Verify that mapped type isn't eagerly resolved in type-to-string operation
|
||||
|
||||
declare function f1<A extends string, B extends string>(a: A, b: B): { [P in A | B]: any };
|
||||
>f1 : Symbol(f1, Decl(deferredLookupTypeResolution.ts, 12, 43))
|
||||
>A : Symbol(A, Decl(deferredLookupTypeResolution.ts, 16, 20))
|
||||
>B : Symbol(B, Decl(deferredLookupTypeResolution.ts, 16, 37))
|
||||
>a : Symbol(a, Decl(deferredLookupTypeResolution.ts, 16, 56))
|
||||
>A : Symbol(A, Decl(deferredLookupTypeResolution.ts, 16, 20))
|
||||
>b : Symbol(b, Decl(deferredLookupTypeResolution.ts, 16, 61))
|
||||
>B : Symbol(B, Decl(deferredLookupTypeResolution.ts, 16, 37))
|
||||
>P : Symbol(P, Decl(deferredLookupTypeResolution.ts, 16, 72))
|
||||
>A : Symbol(A, Decl(deferredLookupTypeResolution.ts, 16, 20))
|
||||
>B : Symbol(B, Decl(deferredLookupTypeResolution.ts, 16, 37))
|
||||
|
||||
function f2<A extends string>(a: A) {
|
||||
>f2 : Symbol(f2, Decl(deferredLookupTypeResolution.ts, 16, 91))
|
||||
>A : Symbol(A, Decl(deferredLookupTypeResolution.ts, 18, 12))
|
||||
>a : Symbol(a, Decl(deferredLookupTypeResolution.ts, 18, 30))
|
||||
>A : Symbol(A, Decl(deferredLookupTypeResolution.ts, 18, 12))
|
||||
|
||||
return f1(a, 'x');
|
||||
>f1 : Symbol(f1, Decl(deferredLookupTypeResolution.ts, 12, 43))
|
||||
>a : Symbol(a, Decl(deferredLookupTypeResolution.ts, 18, 30))
|
||||
}
|
||||
|
||||
function f3(x: 'a' | 'b') {
|
||||
>f3 : Symbol(f3, Decl(deferredLookupTypeResolution.ts, 20, 1))
|
||||
>x : Symbol(x, Decl(deferredLookupTypeResolution.ts, 22, 12))
|
||||
|
||||
return f2(x);
|
||||
>f2 : Symbol(f2, Decl(deferredLookupTypeResolution.ts, 16, 91))
|
||||
>x : Symbol(x, Decl(deferredLookupTypeResolution.ts, 22, 12))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
=== tests/cases/compiler/deferredLookupTypeResolution.ts ===
|
||||
// Repro from #17456
|
||||
|
||||
type StringContains<S extends string, L extends string> = (
|
||||
>StringContains : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L]
|
||||
>S : S
|
||||
>L : L
|
||||
|
||||
{ [K in S]: 'true' } &
|
||||
>K : K
|
||||
>S : S
|
||||
|
||||
{ [key: string]: 'false' }
|
||||
>key : string
|
||||
|
||||
)[L]
|
||||
>L : L
|
||||
|
||||
type ObjectHasKey<O, L extends string> = StringContains<keyof O, L>
|
||||
>ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L]
|
||||
>O : O
|
||||
>L : L
|
||||
>StringContains : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L]
|
||||
>O : O
|
||||
>L : L
|
||||
|
||||
type First<T> = ObjectHasKey<T, '0'>; // Should be deferred
|
||||
>First : ({ [K in S]: "true"; } & { [key: string]: "false"; })["0"]
|
||||
>T : T
|
||||
>ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L]
|
||||
>T : T
|
||||
|
||||
type T1 = ObjectHasKey<{ a: string }, 'a'>; // 'true'
|
||||
>T1 : "true"
|
||||
>ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L]
|
||||
>a : string
|
||||
|
||||
type T2 = ObjectHasKey<{ a: string }, 'b'>; // 'false'
|
||||
>T2 : "false"
|
||||
>ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L]
|
||||
>a : string
|
||||
|
||||
// Verify that mapped type isn't eagerly resolved in type-to-string operation
|
||||
|
||||
declare function f1<A extends string, B extends string>(a: A, b: B): { [P in A | B]: any };
|
||||
>f1 : <A extends string, B extends string>(a: A, b: B) => { [P in A | B]: any; }
|
||||
>A : A
|
||||
>B : B
|
||||
>a : A
|
||||
>A : A
|
||||
>b : B
|
||||
>B : B
|
||||
>P : P
|
||||
>A : A
|
||||
>B : B
|
||||
|
||||
function f2<A extends string>(a: A) {
|
||||
>f2 : <A extends string>(a: A) => { [P in A | B]: any; }
|
||||
>A : A
|
||||
>a : A
|
||||
>A : A
|
||||
|
||||
return f1(a, 'x');
|
||||
>f1(a, 'x') : { [P in A | B]: any; }
|
||||
>f1 : <A extends string, B extends string>(a: A, b: B) => { [P in A | B]: any; }
|
||||
>a : A
|
||||
>'x' : "x"
|
||||
}
|
||||
|
||||
function f3(x: 'a' | 'b') {
|
||||
>f3 : (x: "a" | "b") => { a: any; b: any; x: any; }
|
||||
>x : "a" | "b"
|
||||
|
||||
return f2(x);
|
||||
>f2(x) : { a: any; b: any; x: any; }
|
||||
>f2 : <A extends string>(a: A) => { [P in A | B]: any; }
|
||||
>x : "a" | "b"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
tests/cases/compiler/deferredLookupTypeResolution2.ts(14,13): error TS2536: Type '({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]' cannot be used to index type '{ true: "true"; }'.
|
||||
tests/cases/compiler/deferredLookupTypeResolution2.ts(19,21): error TS2536: Type '({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]]' cannot be used to index type '{ true: "true"; }'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/deferredLookupTypeResolution2.ts (2 errors) ====
|
||||
// Repro from #17456
|
||||
|
||||
type StringContains<S extends string, L extends string> = ({ [K in S]: 'true' } & { [key: string]: 'false'})[L];
|
||||
|
||||
type ObjectHasKey<O, L extends string> = StringContains<keyof O, L>;
|
||||
|
||||
type A<T> = ObjectHasKey<T, '0'>;
|
||||
|
||||
type B = ObjectHasKey<[string, number], '1'>; // "true"
|
||||
type C = ObjectHasKey<[string, number], '2'>; // "false"
|
||||
type D = A<[string]>; // "true"
|
||||
|
||||
// Error, "false" not handled
|
||||
type E<T> = { true: 'true' }[ObjectHasKey<T, '1'>];
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2536: Type '({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]' cannot be used to index type '{ true: "true"; }'.
|
||||
|
||||
type Juxtapose<T> = ({ true: 'otherwise' } & { [k: string]: 'true' })[ObjectHasKey<T, '1'>];
|
||||
|
||||
// Error, "otherwise" is missing
|
||||
type DeepError<T> = { true: 'true' }[Juxtapose<T>];
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2536: Type '({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]]' cannot be used to index type '{ true: "true"; }'.
|
||||
|
||||
type DeepOK<T> = { true: 'true', otherwise: 'false' }[Juxtapose<T>];
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
//// [deferredLookupTypeResolution2.ts]
|
||||
// Repro from #17456
|
||||
|
||||
type StringContains<S extends string, L extends string> = ({ [K in S]: 'true' } & { [key: string]: 'false'})[L];
|
||||
|
||||
type ObjectHasKey<O, L extends string> = StringContains<keyof O, L>;
|
||||
|
||||
type A<T> = ObjectHasKey<T, '0'>;
|
||||
|
||||
type B = ObjectHasKey<[string, number], '1'>; // "true"
|
||||
type C = ObjectHasKey<[string, number], '2'>; // "false"
|
||||
type D = A<[string]>; // "true"
|
||||
|
||||
// Error, "false" not handled
|
||||
type E<T> = { true: 'true' }[ObjectHasKey<T, '1'>];
|
||||
|
||||
type Juxtapose<T> = ({ true: 'otherwise' } & { [k: string]: 'true' })[ObjectHasKey<T, '1'>];
|
||||
|
||||
// Error, "otherwise" is missing
|
||||
type DeepError<T> = { true: 'true' }[Juxtapose<T>];
|
||||
|
||||
type DeepOK<T> = { true: 'true', otherwise: 'false' }[Juxtapose<T>];
|
||||
|
||||
|
||||
//// [deferredLookupTypeResolution2.js]
|
||||
"use strict";
|
||||
// Repro from #17456
|
||||
|
||||
|
||||
//// [deferredLookupTypeResolution2.d.ts]
|
||||
declare type StringContains<S extends string, L extends string> = ({
|
||||
[K in S]: 'true';
|
||||
} & {
|
||||
[key: string]: 'false';
|
||||
})[L];
|
||||
declare type ObjectHasKey<O, L extends string> = StringContains<keyof O, L>;
|
||||
declare type A<T> = ObjectHasKey<T, '0'>;
|
||||
declare type B = ObjectHasKey<[string, number], '1'>;
|
||||
declare type C = ObjectHasKey<[string, number], '2'>;
|
||||
declare type D = A<[string]>;
|
||||
declare type E<T> = {
|
||||
true: 'true';
|
||||
}[ObjectHasKey<T, '1'>];
|
||||
declare type Juxtapose<T> = ({
|
||||
true: 'otherwise';
|
||||
} & {
|
||||
[k: string]: 'true';
|
||||
})[ObjectHasKey<T, '1'>];
|
||||
declare type DeepError<T> = {
|
||||
true: 'true';
|
||||
}[Juxtapose<T>];
|
||||
declare type DeepOK<T> = {
|
||||
true: 'true';
|
||||
otherwise: 'false';
|
||||
}[Juxtapose<T>];
|
||||
@@ -0,0 +1,11 @@
|
||||
//// [doNotInferUnrelatedTypes.ts]
|
||||
// #16709
|
||||
declare function dearray<T>(ara: ReadonlyArray<T>): T;
|
||||
type LiteralType = "foo" | "bar";
|
||||
declare var alt: Array<LiteralType>;
|
||||
|
||||
let foo: LiteralType = dearray(alt);
|
||||
|
||||
|
||||
//// [doNotInferUnrelatedTypes.js]
|
||||
var foo = dearray(alt);
|
||||
@@ -0,0 +1,24 @@
|
||||
=== tests/cases/compiler/doNotInferUnrelatedTypes.ts ===
|
||||
// #16709
|
||||
declare function dearray<T>(ara: ReadonlyArray<T>): T;
|
||||
>dearray : Symbol(dearray, Decl(doNotInferUnrelatedTypes.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(doNotInferUnrelatedTypes.ts, 1, 25))
|
||||
>ara : Symbol(ara, Decl(doNotInferUnrelatedTypes.ts, 1, 28))
|
||||
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(doNotInferUnrelatedTypes.ts, 1, 25))
|
||||
>T : Symbol(T, Decl(doNotInferUnrelatedTypes.ts, 1, 25))
|
||||
|
||||
type LiteralType = "foo" | "bar";
|
||||
>LiteralType : Symbol(LiteralType, Decl(doNotInferUnrelatedTypes.ts, 1, 54))
|
||||
|
||||
declare var alt: Array<LiteralType>;
|
||||
>alt : Symbol(alt, Decl(doNotInferUnrelatedTypes.ts, 3, 11))
|
||||
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>LiteralType : Symbol(LiteralType, Decl(doNotInferUnrelatedTypes.ts, 1, 54))
|
||||
|
||||
let foo: LiteralType = dearray(alt);
|
||||
>foo : Symbol(foo, Decl(doNotInferUnrelatedTypes.ts, 5, 3))
|
||||
>LiteralType : Symbol(LiteralType, Decl(doNotInferUnrelatedTypes.ts, 1, 54))
|
||||
>dearray : Symbol(dearray, Decl(doNotInferUnrelatedTypes.ts, 0, 0))
|
||||
>alt : Symbol(alt, Decl(doNotInferUnrelatedTypes.ts, 3, 11))
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
=== tests/cases/compiler/doNotInferUnrelatedTypes.ts ===
|
||||
// #16709
|
||||
declare function dearray<T>(ara: ReadonlyArray<T>): T;
|
||||
>dearray : <T>(ara: ReadonlyArray<T>) => T
|
||||
>T : T
|
||||
>ara : ReadonlyArray<T>
|
||||
>ReadonlyArray : ReadonlyArray<T>
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
type LiteralType = "foo" | "bar";
|
||||
>LiteralType : LiteralType
|
||||
|
||||
declare var alt: Array<LiteralType>;
|
||||
>alt : LiteralType[]
|
||||
>Array : T[]
|
||||
>LiteralType : LiteralType
|
||||
|
||||
let foo: LiteralType = dearray(alt);
|
||||
>foo : LiteralType
|
||||
>LiteralType : LiteralType
|
||||
>dearray(alt) : LiteralType
|
||||
>dearray : <T>(ara: ReadonlyArray<T>) => T
|
||||
>alt : LiteralType[]
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
tests/cases/compiler/base.d.ts(1,23): error TS1005: ',' expected.
|
||||
tests/cases/compiler/base.d.ts(1,34): error TS1005: '=' expected.
|
||||
tests/cases/compiler/boolean.ts(7,23): error TS1005: ',' expected.
|
||||
tests/cases/compiler/boolean.ts(7,24): error TS1134: Variable declaration expected.
|
||||
tests/cases/compiler/boolean.ts(11,16): error TS2304: Cannot find name 'document'.
|
||||
tests/cases/compiler/boolean.ts(12,22): error TS1005: ';' expected.
|
||||
tests/cases/compiler/number.ts(7,26): error TS1005: ',' expected.
|
||||
tests/cases/compiler/number.ts(7,27): error TS1134: Variable declaration expected.
|
||||
tests/cases/compiler/number.ts(11,16): error TS2304: Cannot find name 'document'.
|
||||
tests/cases/compiler/number.ts(12,20): error TS1005: ';' expected.
|
||||
tests/cases/compiler/string.ts(7,20): error TS1005: ',' expected.
|
||||
tests/cases/compiler/string.ts(7,21): error TS1134: Variable declaration expected.
|
||||
tests/cases/compiler/string.ts(11,15): error TS2304: Cannot find name 'document'.
|
||||
tests/cases/compiler/string.ts(12,19): error TS1005: ';' expected.
|
||||
|
||||
|
||||
==== tests/cases/compiler/base.d.ts (2 errors) ====
|
||||
declare const x: "foo".charCodeAt(0);
|
||||
~
|
||||
!!! error TS1005: ',' expected.
|
||||
~
|
||||
!!! error TS1005: '=' expected.
|
||||
|
||||
==== tests/cases/compiler/string.ts (4 errors) ====
|
||||
interface String {
|
||||
typeof<T>(x: T): T;
|
||||
}
|
||||
|
||||
class C {
|
||||
foo() {
|
||||
const x: "".typeof(this.foo);
|
||||
~
|
||||
!!! error TS1005: ',' expected.
|
||||
~~~~~~
|
||||
!!! error TS1134: Variable declaration expected.
|
||||
}
|
||||
}
|
||||
|
||||
const nodes = document.getElementsByTagName("li");
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'document'.
|
||||
type ItemType = "".typeof(nodes.item(0));
|
||||
~
|
||||
!!! error TS1005: ';' expected.
|
||||
|
||||
==== tests/cases/compiler/number.ts (4 errors) ====
|
||||
interface Number {
|
||||
typeof<T>(x: T): T;
|
||||
}
|
||||
|
||||
class C2 {
|
||||
foo() {
|
||||
const x: 3.141592.typeof(this.foo);
|
||||
~
|
||||
!!! error TS1005: ',' expected.
|
||||
~~~~~~
|
||||
!!! error TS1134: Variable declaration expected.
|
||||
}
|
||||
}
|
||||
|
||||
const nodes2 = document.getElementsByTagName("li");
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'document'.
|
||||
type ItemType2 = 4..typeof(nodes.item(0));
|
||||
~
|
||||
!!! error TS1005: ';' expected.
|
||||
|
||||
==== tests/cases/compiler/boolean.ts (4 errors) ====
|
||||
interface Boolean {
|
||||
typeof<T>(x: T): T;
|
||||
}
|
||||
|
||||
class C3 {
|
||||
foo() {
|
||||
const x: false.typeof(this.foo);
|
||||
~
|
||||
!!! error TS1005: ',' expected.
|
||||
~~~~~~
|
||||
!!! error TS1134: Variable declaration expected.
|
||||
}
|
||||
}
|
||||
|
||||
const nodes3 = document.getElementsByTagName("li");
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'document'.
|
||||
type ItemType3 = true.typeof(nodes.item(0));
|
||||
~
|
||||
!!! error TS1005: ';' expected.
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
//// [tests/cases/compiler/expressionTypeNodeShouldError.ts] ////
|
||||
|
||||
//// [base.d.ts]
|
||||
declare const x: "foo".charCodeAt(0);
|
||||
|
||||
//// [string.ts]
|
||||
interface String {
|
||||
typeof<T>(x: T): T;
|
||||
}
|
||||
|
||||
class C {
|
||||
foo() {
|
||||
const x: "".typeof(this.foo);
|
||||
}
|
||||
}
|
||||
|
||||
const nodes = document.getElementsByTagName("li");
|
||||
type ItemType = "".typeof(nodes.item(0));
|
||||
|
||||
//// [number.ts]
|
||||
interface Number {
|
||||
typeof<T>(x: T): T;
|
||||
}
|
||||
|
||||
class C2 {
|
||||
foo() {
|
||||
const x: 3.141592.typeof(this.foo);
|
||||
}
|
||||
}
|
||||
|
||||
const nodes2 = document.getElementsByTagName("li");
|
||||
type ItemType2 = 4..typeof(nodes.item(0));
|
||||
|
||||
//// [boolean.ts]
|
||||
interface Boolean {
|
||||
typeof<T>(x: T): T;
|
||||
}
|
||||
|
||||
class C3 {
|
||||
foo() {
|
||||
const x: false.typeof(this.foo);
|
||||
}
|
||||
}
|
||||
|
||||
const nodes3 = document.getElementsByTagName("li");
|
||||
type ItemType3 = true.typeof(nodes.item(0));
|
||||
|
||||
|
||||
|
||||
//// [string.js]
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
C.prototype.foo = function () {
|
||||
var x;
|
||||
typeof (this.foo);
|
||||
};
|
||||
return C;
|
||||
}());
|
||||
var nodes = document.getElementsByTagName("li");
|
||||
typeof (nodes.item(0));
|
||||
//// [number.js]
|
||||
var C2 = (function () {
|
||||
function C2() {
|
||||
}
|
||||
C2.prototype.foo = function () {
|
||||
var x;
|
||||
typeof (this.foo);
|
||||
};
|
||||
return C2;
|
||||
}());
|
||||
var nodes2 = document.getElementsByTagName("li");
|
||||
typeof (nodes.item(0));
|
||||
//// [boolean.js]
|
||||
var C3 = (function () {
|
||||
function C3() {
|
||||
}
|
||||
C3.prototype.foo = function () {
|
||||
var x;
|
||||
typeof (this.foo);
|
||||
};
|
||||
return C3;
|
||||
}());
|
||||
var nodes3 = document.getElementsByTagName("li");
|
||||
typeof (nodes.item(0));
|
||||
@@ -0,0 +1,47 @@
|
||||
tests/cases/compiler/indexSignatureAndMappedType.ts(6,5): error TS2322: Type '{ [key: string]: T; }' is not assignable to type 'Record<K, T>'.
|
||||
tests/cases/compiler/indexSignatureAndMappedType.ts(15,5): error TS2322: Type 'Record<K, U>' is not assignable to type '{ [key: string]: T; }'.
|
||||
Type 'U' is not assignable to type 'T'.
|
||||
tests/cases/compiler/indexSignatureAndMappedType.ts(16,5): error TS2322: Type '{ [key: string]: T; }' is not assignable to type 'Record<K, U>'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/indexSignatureAndMappedType.ts (3 errors) ====
|
||||
// A mapped type { [P in K]: X }, where K is a generic type, is related to
|
||||
// { [key: string]: Y } if X is related to Y.
|
||||
|
||||
function f1<T, K extends string>(x: { [key: string]: T }, y: Record<K, T>) {
|
||||
x = y;
|
||||
y = x; // Error
|
||||
~
|
||||
!!! error TS2322: Type '{ [key: string]: T; }' is not assignable to type 'Record<K, T>'.
|
||||
}
|
||||
|
||||
function f2<T>(x: { [key: string]: T }, y: Record<string, T>) {
|
||||
x = y;
|
||||
y = x;
|
||||
}
|
||||
|
||||
function f3<T, U, K extends string>(x: { [key: string]: T }, y: Record<K, U>) {
|
||||
x = y; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'Record<K, U>' is not assignable to type '{ [key: string]: T; }'.
|
||||
!!! error TS2322: Type 'U' is not assignable to type 'T'.
|
||||
y = x; // Error
|
||||
~
|
||||
!!! error TS2322: Type '{ [key: string]: T; }' is not assignable to type 'Record<K, U>'.
|
||||
}
|
||||
|
||||
// Repro from #14548
|
||||
|
||||
type Dictionary = {
|
||||
[key: string]: string;
|
||||
};
|
||||
|
||||
interface IBaseEntity {
|
||||
name: string;
|
||||
properties: Dictionary;
|
||||
}
|
||||
|
||||
interface IEntity<T extends string> extends IBaseEntity {
|
||||
properties: Record<T, string>;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
//// [indexSignatureAndMappedType.ts]
|
||||
// A mapped type { [P in K]: X }, where K is a generic type, is related to
|
||||
// { [key: string]: Y } if X is related to Y.
|
||||
|
||||
function f1<T, K extends string>(x: { [key: string]: T }, y: Record<K, T>) {
|
||||
x = y;
|
||||
y = x; // Error
|
||||
}
|
||||
|
||||
function f2<T>(x: { [key: string]: T }, y: Record<string, T>) {
|
||||
x = y;
|
||||
y = x;
|
||||
}
|
||||
|
||||
function f3<T, U, K extends string>(x: { [key: string]: T }, y: Record<K, U>) {
|
||||
x = y; // Error
|
||||
y = x; // Error
|
||||
}
|
||||
|
||||
// Repro from #14548
|
||||
|
||||
type Dictionary = {
|
||||
[key: string]: string;
|
||||
};
|
||||
|
||||
interface IBaseEntity {
|
||||
name: string;
|
||||
properties: Dictionary;
|
||||
}
|
||||
|
||||
interface IEntity<T extends string> extends IBaseEntity {
|
||||
properties: Record<T, string>;
|
||||
}
|
||||
|
||||
|
||||
//// [indexSignatureAndMappedType.js]
|
||||
"use strict";
|
||||
// A mapped type { [P in K]: X }, where K is a generic type, is related to
|
||||
// { [key: string]: Y } if X is related to Y.
|
||||
function f1(x, y) {
|
||||
x = y;
|
||||
y = x; // Error
|
||||
}
|
||||
function f2(x, y) {
|
||||
x = y;
|
||||
y = x;
|
||||
}
|
||||
function f3(x, y) {
|
||||
x = y; // Error
|
||||
y = x; // Error
|
||||
}
|
||||
|
||||
|
||||
//// [indexSignatureAndMappedType.d.ts]
|
||||
declare function f1<T, K extends string>(x: {
|
||||
[key: string]: T;
|
||||
}, y: Record<K, T>): void;
|
||||
declare function f2<T>(x: {
|
||||
[key: string]: T;
|
||||
}, y: Record<string, T>): void;
|
||||
declare function f3<T, U, K extends string>(x: {
|
||||
[key: string]: T;
|
||||
}, y: Record<K, U>): void;
|
||||
declare type Dictionary = {
|
||||
[key: string]: string;
|
||||
};
|
||||
interface IBaseEntity {
|
||||
name: string;
|
||||
properties: Dictionary;
|
||||
}
|
||||
interface IEntity<T extends string> extends IBaseEntity {
|
||||
properties: Record<T, string>;
|
||||
}
|
||||
@@ -97,7 +97,7 @@ var a;
|
||||
/** @type {string} */
|
||||
var s;
|
||||
var a = ("" + 4);
|
||||
var s = "" + (4);
|
||||
var s = "" +/** @type {*} */ (4);
|
||||
var SomeBase = (function () {
|
||||
function SomeBase() {
|
||||
this.p = 42;
|
||||
@@ -128,19 +128,19 @@ var someBase = new SomeBase();
|
||||
var someDerived = new SomeDerived();
|
||||
var someOther = new SomeOther();
|
||||
var someFakeClass = new SomeFakeClass();
|
||||
someBase = (someDerived);
|
||||
someBase = (someBase);
|
||||
someBase = (someOther); // Error
|
||||
someDerived = (someDerived);
|
||||
someDerived = (someBase);
|
||||
someDerived = (someOther); // Error
|
||||
someOther = (someDerived); // Error
|
||||
someOther = (someBase); // Error
|
||||
someOther = (someOther);
|
||||
someBase =/** @type {SomeBase} */ (someDerived);
|
||||
someBase =/** @type {SomeBase} */ (someBase);
|
||||
someBase =/** @type {SomeBase} */ (someOther); // Error
|
||||
someDerived =/** @type {SomeDerived} */ (someDerived);
|
||||
someDerived =/** @type {SomeDerived} */ (someBase);
|
||||
someDerived =/** @type {SomeDerived} */ (someOther); // Error
|
||||
someOther =/** @type {SomeOther} */ (someDerived); // Error
|
||||
someOther =/** @type {SomeOther} */ (someBase); // Error
|
||||
someOther =/** @type {SomeOther} */ (someOther);
|
||||
someFakeClass = someBase;
|
||||
someFakeClass = someDerived;
|
||||
someBase = someFakeClass; // Error
|
||||
someBase = (someFakeClass);
|
||||
someBase =/** @type {SomeBase} */ (someFakeClass);
|
||||
// Type assertion cannot be a type-predicate type
|
||||
/** @type {number | string} */
|
||||
var numOrStr;
|
||||
|
||||
@@ -41,9 +41,9 @@ function testcase() {
|
||||
var one = 1;
|
||||
var _float = -(4 / 3);
|
||||
var a = new Array(false, undefined, null, "0", obj, -1.3333333333333, "str", -0, true, +0, one, 1, 0, false, _float, -(4 / 3));
|
||||
if (a.indexOf(-(4 / 3)) === 14 &&
|
||||
a.indexOf(0) === 7 &&
|
||||
a.indexOf(-0) === 7 &&
|
||||
if (a.indexOf(-(4 / 3)) === 14 &&// a[14]=_float===-(4/3)
|
||||
a.indexOf(0) === 7 &&// a[7] = +0, 0===+0
|
||||
a.indexOf(-0) === 7 &&// a[7] = +0, -0===+0
|
||||
a.indexOf(1) === 10) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
|
||||
//// [parserGreaterThanTokenAmbiguity10.js]
|
||||
1
|
||||
>>>
|
||||
// before
|
||||
>>>// after
|
||||
2;
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
|
||||
//// [parserGreaterThanTokenAmbiguity15.js]
|
||||
1
|
||||
>>=
|
||||
// before
|
||||
>>=// after
|
||||
2;
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
|
||||
//// [parserGreaterThanTokenAmbiguity20.js]
|
||||
1
|
||||
>>>=
|
||||
// Before
|
||||
>>>=// after
|
||||
2;
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
|
||||
//// [parserGreaterThanTokenAmbiguity5.js]
|
||||
1
|
||||
>>
|
||||
// before
|
||||
>>// after
|
||||
2;
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
//// [signatureInstantiationWithRecursiveConstraints.ts]
|
||||
// Repro from #17148
|
||||
|
||||
class Foo {
|
||||
myFunc<T extends Foo>(arg: T) {}
|
||||
}
|
||||
|
||||
class Bar {
|
||||
myFunc<T extends Bar>(arg: T) {}
|
||||
}
|
||||
|
||||
const myVar: Foo = new Bar();
|
||||
|
||||
|
||||
//// [signatureInstantiationWithRecursiveConstraints.js]
|
||||
"use strict";
|
||||
// Repro from #17148
|
||||
var Foo = (function () {
|
||||
function Foo() {
|
||||
}
|
||||
Foo.prototype.myFunc = function (arg) { };
|
||||
return Foo;
|
||||
}());
|
||||
var Bar = (function () {
|
||||
function Bar() {
|
||||
}
|
||||
Bar.prototype.myFunc = function (arg) { };
|
||||
return Bar;
|
||||
}());
|
||||
var myVar = new Bar();
|
||||
@@ -0,0 +1,30 @@
|
||||
=== tests/cases/compiler/signatureInstantiationWithRecursiveConstraints.ts ===
|
||||
// Repro from #17148
|
||||
|
||||
class Foo {
|
||||
>Foo : Symbol(Foo, Decl(signatureInstantiationWithRecursiveConstraints.ts, 0, 0))
|
||||
|
||||
myFunc<T extends Foo>(arg: T) {}
|
||||
>myFunc : Symbol(Foo.myFunc, Decl(signatureInstantiationWithRecursiveConstraints.ts, 2, 11))
|
||||
>T : Symbol(T, Decl(signatureInstantiationWithRecursiveConstraints.ts, 3, 9))
|
||||
>Foo : Symbol(Foo, Decl(signatureInstantiationWithRecursiveConstraints.ts, 0, 0))
|
||||
>arg : Symbol(arg, Decl(signatureInstantiationWithRecursiveConstraints.ts, 3, 24))
|
||||
>T : Symbol(T, Decl(signatureInstantiationWithRecursiveConstraints.ts, 3, 9))
|
||||
}
|
||||
|
||||
class Bar {
|
||||
>Bar : Symbol(Bar, Decl(signatureInstantiationWithRecursiveConstraints.ts, 4, 1))
|
||||
|
||||
myFunc<T extends Bar>(arg: T) {}
|
||||
>myFunc : Symbol(Bar.myFunc, Decl(signatureInstantiationWithRecursiveConstraints.ts, 6, 11))
|
||||
>T : Symbol(T, Decl(signatureInstantiationWithRecursiveConstraints.ts, 7, 9))
|
||||
>Bar : Symbol(Bar, Decl(signatureInstantiationWithRecursiveConstraints.ts, 4, 1))
|
||||
>arg : Symbol(arg, Decl(signatureInstantiationWithRecursiveConstraints.ts, 7, 24))
|
||||
>T : Symbol(T, Decl(signatureInstantiationWithRecursiveConstraints.ts, 7, 9))
|
||||
}
|
||||
|
||||
const myVar: Foo = new Bar();
|
||||
>myVar : Symbol(myVar, Decl(signatureInstantiationWithRecursiveConstraints.ts, 10, 5))
|
||||
>Foo : Symbol(Foo, Decl(signatureInstantiationWithRecursiveConstraints.ts, 0, 0))
|
||||
>Bar : Symbol(Bar, Decl(signatureInstantiationWithRecursiveConstraints.ts, 4, 1))
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
=== tests/cases/compiler/signatureInstantiationWithRecursiveConstraints.ts ===
|
||||
// Repro from #17148
|
||||
|
||||
class Foo {
|
||||
>Foo : Foo
|
||||
|
||||
myFunc<T extends Foo>(arg: T) {}
|
||||
>myFunc : <T extends Foo>(arg: T) => void
|
||||
>T : T
|
||||
>Foo : Foo
|
||||
>arg : T
|
||||
>T : T
|
||||
}
|
||||
|
||||
class Bar {
|
||||
>Bar : Bar
|
||||
|
||||
myFunc<T extends Bar>(arg: T) {}
|
||||
>myFunc : <T extends Bar>(arg: T) => void
|
||||
>T : T
|
||||
>Bar : Bar
|
||||
>arg : T
|
||||
>T : T
|
||||
}
|
||||
|
||||
const myVar: Foo = new Bar();
|
||||
>myVar : Foo
|
||||
>Foo : Foo
|
||||
>new Bar() : Bar
|
||||
>Bar : typeof Bar
|
||||
|
||||
@@ -138,7 +138,7 @@ function foo8(x) {
|
||||
var b;
|
||||
return typeof x === "string"
|
||||
? x === "hello"
|
||||
: ((b = x) &&
|
||||
: ((b = x) &&// number | boolean
|
||||
(typeof x === "boolean"
|
||||
? x // boolean
|
||||
: x == 10)); // boolean
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
var a = 'some'
|
||||
// comment
|
||||
+ 'text';
|
||||
|
||||
var b = 'some'
|
||||
/* comment */
|
||||
+ 'text';
|
||||
|
||||
var c = 'some'
|
||||
/* comment */
|
||||
+ /*comment1*/
|
||||
'text';
|
||||
@@ -0,0 +1,13 @@
|
||||
// @removeComments: true
|
||||
var a = 'some'
|
||||
// comment
|
||||
+ 'text';
|
||||
|
||||
var b = 'some'
|
||||
/* comment */
|
||||
+ 'text';
|
||||
|
||||
var c = 'some'
|
||||
/* comment */
|
||||
+ /*comment1*/
|
||||
'text';
|
||||
@@ -0,0 +1,28 @@
|
||||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
// Repro from #17456
|
||||
|
||||
type StringContains<S extends string, L extends string> = (
|
||||
{ [K in S]: 'true' } &
|
||||
{ [key: string]: 'false' }
|
||||
)[L]
|
||||
|
||||
type ObjectHasKey<O, L extends string> = StringContains<keyof O, L>
|
||||
|
||||
type First<T> = ObjectHasKey<T, '0'>; // Should be deferred
|
||||
|
||||
type T1 = ObjectHasKey<{ a: string }, 'a'>; // 'true'
|
||||
type T2 = ObjectHasKey<{ a: string }, 'b'>; // 'false'
|
||||
|
||||
// Verify that mapped type isn't eagerly resolved in type-to-string operation
|
||||
|
||||
declare function f1<A extends string, B extends string>(a: A, b: B): { [P in A | B]: any };
|
||||
|
||||
function f2<A extends string>(a: A) {
|
||||
return f1(a, 'x');
|
||||
}
|
||||
|
||||
function f3(x: 'a' | 'b') {
|
||||
return f2(x);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
// Repro from #17456
|
||||
|
||||
type StringContains<S extends string, L extends string> = ({ [K in S]: 'true' } & { [key: string]: 'false'})[L];
|
||||
|
||||
type ObjectHasKey<O, L extends string> = StringContains<keyof O, L>;
|
||||
|
||||
type A<T> = ObjectHasKey<T, '0'>;
|
||||
|
||||
type B = ObjectHasKey<[string, number], '1'>; // "true"
|
||||
type C = ObjectHasKey<[string, number], '2'>; // "false"
|
||||
type D = A<[string]>; // "true"
|
||||
|
||||
// Error, "false" not handled
|
||||
type E<T> = { true: 'true' }[ObjectHasKey<T, '1'>];
|
||||
|
||||
type Juxtapose<T> = ({ true: 'otherwise' } & { [k: string]: 'true' })[ObjectHasKey<T, '1'>];
|
||||
|
||||
// Error, "otherwise" is missing
|
||||
type DeepError<T> = { true: 'true' }[Juxtapose<T>];
|
||||
|
||||
type DeepOK<T> = { true: 'true', otherwise: 'false' }[Juxtapose<T>];
|
||||
@@ -0,0 +1,6 @@
|
||||
// #16709
|
||||
declare function dearray<T>(ara: ReadonlyArray<T>): T;
|
||||
type LiteralType = "foo" | "bar";
|
||||
declare var alt: Array<LiteralType>;
|
||||
|
||||
let foo: LiteralType = dearray(alt);
|
||||
@@ -0,0 +1,45 @@
|
||||
// @Filename: base.d.ts
|
||||
declare const x: "foo".charCodeAt(0);
|
||||
|
||||
// @filename: string.ts
|
||||
interface String {
|
||||
typeof<T>(x: T): T;
|
||||
}
|
||||
|
||||
class C {
|
||||
foo() {
|
||||
const x: "".typeof(this.foo);
|
||||
}
|
||||
}
|
||||
|
||||
const nodes = document.getElementsByTagName("li");
|
||||
type ItemType = "".typeof(nodes.item(0));
|
||||
|
||||
// @filename: number.ts
|
||||
interface Number {
|
||||
typeof<T>(x: T): T;
|
||||
}
|
||||
|
||||
class C2 {
|
||||
foo() {
|
||||
const x: 3.141592.typeof(this.foo);
|
||||
}
|
||||
}
|
||||
|
||||
const nodes2 = document.getElementsByTagName("li");
|
||||
type ItemType2 = 4..typeof(nodes.item(0));
|
||||
|
||||
// @filename: boolean.ts
|
||||
interface Boolean {
|
||||
typeof<T>(x: T): T;
|
||||
}
|
||||
|
||||
class C3 {
|
||||
foo() {
|
||||
const x: false.typeof(this.foo);
|
||||
}
|
||||
}
|
||||
|
||||
const nodes3 = document.getElementsByTagName("li");
|
||||
type ItemType3 = true.typeof(nodes.item(0));
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
// A mapped type { [P in K]: X }, where K is a generic type, is related to
|
||||
// { [key: string]: Y } if X is related to Y.
|
||||
|
||||
function f1<T, K extends string>(x: { [key: string]: T }, y: Record<K, T>) {
|
||||
x = y;
|
||||
y = x; // Error
|
||||
}
|
||||
|
||||
function f2<T>(x: { [key: string]: T }, y: Record<string, T>) {
|
||||
x = y;
|
||||
y = x;
|
||||
}
|
||||
|
||||
function f3<T, U, K extends string>(x: { [key: string]: T }, y: Record<K, U>) {
|
||||
x = y; // Error
|
||||
y = x; // Error
|
||||
}
|
||||
|
||||
// Repro from #14548
|
||||
|
||||
type Dictionary = {
|
||||
[key: string]: string;
|
||||
};
|
||||
|
||||
interface IBaseEntity {
|
||||
name: string;
|
||||
properties: Dictionary;
|
||||
}
|
||||
|
||||
interface IEntity<T extends string> extends IBaseEntity {
|
||||
properties: Record<T, string>;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// @strict: true
|
||||
|
||||
// Repro from #17148
|
||||
|
||||
class Foo {
|
||||
myFunc<T extends Foo>(arg: T) {}
|
||||
}
|
||||
|
||||
class Bar {
|
||||
myFunc<T extends Bar>(arg: T) {}
|
||||
}
|
||||
|
||||
const myVar: Foo = new Bar();
|
||||
@@ -0,0 +1,9 @@
|
||||
/// <reference path="fourslash.ts"/>
|
||||
|
||||
////const { b/**/ } = new class {
|
||||
//// private ab;
|
||||
//// protected bc;
|
||||
////}
|
||||
|
||||
goTo.marker();
|
||||
verify.completionListIsEmpty();
|
||||
Reference in New Issue
Block a user