Merge branch 'master' into preserveSourceNewlinesAllTheThings

This commit is contained in:
Andrew Branch
2020-04-08 14:36:41 -07:00
48 changed files with 898 additions and 224 deletions
+72 -23
View File
@@ -195,7 +195,7 @@ namespace ts {
None = 0,
Source = 1 << 0,
Target = 1 << 1,
ExcessCheck = 1 << 2,
PropertyCheck = 1 << 2,
}
const enum MappedTypeModifiers {
@@ -1347,6 +1347,7 @@ namespace ts {
function isBlockScopedNameDeclaredBeforeUse(declaration: Declaration, usage: Node): boolean {
const declarationFile = getSourceFileOfNode(declaration);
const useFile = getSourceFileOfNode(usage);
const declContainer = getEnclosingBlockScopeContainer(declaration);
if (declarationFile !== useFile) {
if ((moduleKind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) ||
(!compilerOptions.outFile && !compilerOptions.out) ||
@@ -1389,11 +1390,10 @@ namespace ts {
return !isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage, /*stopAtAnyPropertyDeclaration*/ false);
}
else if (isParameterPropertyDeclaration(declaration, declaration.parent)) {
const container = getEnclosingBlockScopeContainer(declaration.parent);
// foo = this.bar is illegal in esnext+useDefineForClassFields when bar is a parameter property
return !(compilerOptions.target === ScriptTarget.ESNext && !!compilerOptions.useDefineForClassFields
&& getContainingClass(declaration) === getContainingClass(usage)
&& isUsedInFunctionOrInstanceProperty(usage, declaration, container));
&& isUsedInFunctionOrInstanceProperty(usage, declaration));
}
return true;
}
@@ -1418,11 +1418,10 @@ namespace ts {
return true;
}
const container = getEnclosingBlockScopeContainer(declaration);
if (!!(usage.flags & NodeFlags.JSDoc) || isInTypeQuery(usage)) {
if (!!(usage.flags & NodeFlags.JSDoc) || isInTypeQuery(usage) || usageInTypeDeclaration()) {
return true;
}
if (isUsedInFunctionOrInstanceProperty(usage, declaration, container)) {
if (isUsedInFunctionOrInstanceProperty(usage, declaration)) {
if (compilerOptions.target === ScriptTarget.ESNext && !!compilerOptions.useDefineForClassFields && getContainingClass(declaration)) {
return (isPropertyDeclaration(declaration) || isParameterPropertyDeclaration(declaration, declaration.parent)) &&
!isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage, /*stopAtAnyPropertyDeclaration*/ true);
@@ -1433,16 +1432,18 @@ namespace ts {
}
return false;
function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration: VariableDeclaration, usage: Node): boolean {
const container = getEnclosingBlockScopeContainer(declaration);
function usageInTypeDeclaration() {
return !!findAncestor(usage, node => isInterfaceDeclaration(node) || isTypeAliasDeclaration(node));
}
function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration: VariableDeclaration, usage: Node): boolean {
switch (declaration.parent.parent.kind) {
case SyntaxKind.VariableStatement:
case SyntaxKind.ForStatement:
case SyntaxKind.ForOfStatement:
// variable statement/for/for-of statement case,
// use site should not be inside variable declaration (initializer of declaration or binding element)
if (isSameScopeDescendentOf(usage, declaration, container)) {
if (isSameScopeDescendentOf(usage, declaration, declContainer)) {
return true;
}
break;
@@ -1450,12 +1451,12 @@ namespace ts {
// ForIn/ForOf case - use site should not be used in expression part
const grandparent = declaration.parent.parent;
return isForInOrOfStatement(grandparent) && isSameScopeDescendentOf(usage, grandparent.expression, container);
return isForInOrOfStatement(grandparent) && isSameScopeDescendentOf(usage, grandparent.expression, declContainer);
}
function isUsedInFunctionOrInstanceProperty(usage: Node, declaration: Node, container?: Node): boolean {
function isUsedInFunctionOrInstanceProperty(usage: Node, declaration: Node): boolean {
return !!findAncestor(usage, current => {
if (current === container) {
if (current === declContainer) {
return "quit";
}
if (isFunctionLike(current)) {
@@ -4742,7 +4743,10 @@ namespace ts {
];
}
}
const result = [];
const mayHaveNameCollisions = !(context.flags & NodeBuilderFlags.UseFullyQualifiedType);
/** Map from type reference identifier text to [type, index in `result` where the type node is] */
const seenNames = mayHaveNameCollisions ? createUnderscoreEscapedMultiMap<[Type, number]>() : undefined;
const result: TypeNode[] = [];
let i = 0;
for (const type of types) {
i++;
@@ -4758,13 +4762,42 @@ namespace ts {
const typeNode = typeToTypeNodeHelper(type, context);
if (typeNode) {
result.push(typeNode);
if (seenNames && isIdentifierTypeReference(typeNode)) {
seenNames.add(typeNode.typeName.escapedText, [type, result.length - 1]);
}
}
}
if (seenNames) {
// To avoid printing types like `[Foo, Foo]` or `Bar & Bar` where
// occurrences of the same name actually come from different
// namespaces, go through the single-identifier type reference nodes
// we just generated, and see if any names were generated more than
// once while referring to different types. If so, regenerate the
// type node for each entry by that name with the
// `UseFullyQualifiedType` flag enabled.
const saveContextFlags = context.flags;
context.flags |= NodeBuilderFlags.UseFullyQualifiedType;
seenNames.forEach(types => {
if (!arrayIsHomogeneous(types, ([a], [b]) => typesAreSameReference(a, b))) {
for (const [type, resultIndex] of types) {
result[resultIndex] = typeToTypeNodeHelper(type, context);
}
}
});
context.flags = saveContextFlags;
}
return result;
}
}
function typesAreSameReference(a: Type, b: Type): boolean {
return a === b
|| !!a.symbol && a.symbol === b.symbol
|| !!a.aliasSymbol && a.aliasSymbol === b.aliasSymbol;
}
function indexInfoToIndexSignatureDeclarationHelper(indexInfo: IndexInfo, kind: IndexKind, context: NodeBuilderContext): IndexSignatureDeclaration {
const name = getNameFromIndexInfo(indexInfo) || "x";
const indexerTypeNode = createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword);
@@ -8238,6 +8271,7 @@ namespace ts {
return undefined;
}
switch (node.kind) {
case SyntaxKind.VariableStatement:
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
case SyntaxKind.InterfaceDeclaration:
@@ -8265,6 +8299,9 @@ namespace ts {
else if (node.kind === SyntaxKind.ConditionalType) {
return concatenate(outerTypeParameters, getInferTypeParameters(<ConditionalTypeNode>node));
}
else if (node.kind === SyntaxKind.VariableStatement && !isInJSFile(node)) {
break;
}
const outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, getEffectiveTypeParameterDeclarations(<DeclarationWithTypeParameters>node));
const thisType = includeThisTypes &&
(node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression || node.kind === SyntaxKind.InterfaceDeclaration || isJSConstructor(node)) &&
@@ -15561,7 +15598,7 @@ namespace ts {
if (source.flags & TypeFlags.Union) {
result = relation === comparableRelation ?
someTypeRelatedToType(source as UnionType, target, reportErrors && !(source.flags & TypeFlags.Primitive), intersectionState) :
eachTypeRelatedToType(source as UnionType, target, reportErrors && !(source.flags & TypeFlags.Primitive), intersectionState & IntersectionState.ExcessCheck);
eachTypeRelatedToType(source as UnionType, target, reportErrors && !(source.flags & TypeFlags.Primitive), intersectionState);
}
else {
if (target.flags & TypeFlags.Union) {
@@ -15569,12 +15606,6 @@ namespace ts {
}
else if (target.flags & TypeFlags.Intersection) {
result = typeRelatedToEachType(getRegularTypeOfObjectLiteral(source), target as IntersectionType, reportErrors, IntersectionState.Target);
if (result && (isPerformingExcessPropertyChecks || isPerformingCommonPropertyChecks) && !(intersectionState & IntersectionState.ExcessCheck)) {
// Validate against excess props using the original `source`
if (!propertiesRelatedTo(source, target, reportErrors, /*excludedProperties*/ undefined, IntersectionState.ExcessCheck)) {
return Ternary.False;
}
}
}
else if (source.flags & TypeFlags.Intersection) {
// Check to see if any constituents of the intersection are immediately related to the target.
@@ -15590,9 +15621,7 @@ namespace ts {
//
// - For a primitive type or type parameter (such as 'number = A & B') there is no point in
// breaking the intersection apart.
if (!isNonGenericObjectType(target) || !every((<IntersectionType>source).types, t => isNonGenericObjectType(t) && !(getObjectFlags(t) & ObjectFlags.NonInferrableType))) {
result = someTypeRelatedToType(<IntersectionType>source, target, /*reportErrors*/ false, IntersectionState.Source);
}
result = someTypeRelatedToType(<IntersectionType>source, target, /*reportErrors*/ false, IntersectionState.Source);
}
if (!result && (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable)) {
if (result = recursiveTypeRelatedTo(source, target, reportErrors, intersectionState)) {
@@ -15624,6 +15653,23 @@ namespace ts {
}
}
}
// For certain combinations involving intersections and optional, excess, or mismatched properties we need
// an extra property check where the intersection is viewed as a single object. The following are motivating
// examples that all should be errors, but aren't without this extra property check:
//
// let obj: { a: { x: string } } & { c: number } = { a: { x: 'hello', y: 2 }, c: 5 }; // Nested excess property
//
// declare let wrong: { a: { y: string } };
// let weak: { a?: { x?: number } } & { c?: string } = wrong; // Nested weak object type
//
// function foo<T extends object>(x: { a?: string }, y: T & { a: boolean }) {
// x = y; // Mismatched property in source intersection
// }
if (result && (
target.flags & TypeFlags.Intersection && (isPerformingExcessPropertyChecks || isPerformingCommonPropertyChecks) ||
isNonGenericObjectType(target) && source.flags & TypeFlags.Intersection && getApparentType(source).flags & TypeFlags.StructuredType && !some((<IntersectionType>source).types, t => !!(getObjectFlags(t) & ObjectFlags.NonInferrableType)))) {
result &= recursiveTypeRelatedTo(source, target, reportErrors, IntersectionState.PropertyCheck);
}
if (!result && reportErrors) {
source = originalSource.aliasSymbol ? originalSource : source;
@@ -16000,6 +16046,9 @@ namespace ts {
}
function structuredTypeRelatedTo(source: Type, target: Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary {
if (intersectionState & IntersectionState.PropertyCheck) {
return propertiesRelatedTo(source, target, reportErrors, /*excludedProperties*/ undefined, IntersectionState.None);
}
const flags = source.flags & target.flags;
if (relation === identityRelation && !(flags & TypeFlags.Object)) {
if (flags & TypeFlags.Index) {
+2 -1
View File
@@ -1115,7 +1115,8 @@ namespace ts {
target: ScriptTarget.ES5,
strict: true,
esModuleInterop: true,
forceConsistentCasingInFileNames: true
forceConsistentCasingInFileNames: true,
skipLibCheck: true
};
/* @internal */
+18
View File
@@ -1351,6 +1351,24 @@ namespace ts {
}
}
export interface UnderscoreEscapedMultiMap<T> extends UnderscoreEscapedMap<T[]> {
/**
* Adds the value to an array of values associated with the key, and returns the array.
* Creates the array if it does not already exist.
*/
add(key: __String, value: T): T[];
/**
* Removes a value from an array of values associated with the key.
* Does not preserve the order of those values.
* Does nothing if `key` is not in `map`, or `value` is not in `map[key]`.
*/
remove(key: __String, value: T): void;
}
export function createUnderscoreEscapedMultiMap<T>(): UnderscoreEscapedMultiMap<T> {
return createMultiMap<T>() as UnderscoreEscapedMultiMap<T>;
}
/**
* Tests whether a value is an array.
*/
+2 -2
View File
@@ -307,14 +307,14 @@ namespace ts {
/* @internal */ export function isUnicodeIdentifierStart(code: number, languageVersion: ScriptTarget | undefined) {
return languageVersion! >= ScriptTarget.ES2015 ?
lookupInUnicodeMap(code, unicodeESNextIdentifierStart) :
languageVersion! === ScriptTarget.ES5 ? lookupInUnicodeMap(code, unicodeES5IdentifierStart) :
languageVersion === ScriptTarget.ES5 ? lookupInUnicodeMap(code, unicodeES5IdentifierStart) :
lookupInUnicodeMap(code, unicodeES3IdentifierStart);
}
function isUnicodeIdentifierPart(code: number, languageVersion: ScriptTarget | undefined) {
return languageVersion! >= ScriptTarget.ES2015 ?
lookupInUnicodeMap(code, unicodeESNextIdentifierPart) :
languageVersion! === ScriptTarget.ES5 ? lookupInUnicodeMap(code, unicodeES5IdentifierPart) :
languageVersion === ScriptTarget.ES5 ? lookupInUnicodeMap(code, unicodeES5IdentifierPart) :
lookupInUnicodeMap(code, unicodeES3IdentifierPart);
}
+12
View File
@@ -1590,6 +1590,18 @@ namespace ts {
case SyntaxKind.ImportType:
break;
// handle JSDoc types from an invalid parse
case SyntaxKind.JSDocAllType:
case SyntaxKind.JSDocUnknownType:
case SyntaxKind.JSDocFunctionType:
case SyntaxKind.JSDocVariadicType:
case SyntaxKind.JSDocNamepathType:
break;
case SyntaxKind.JSDocNullableType:
case SyntaxKind.JSDocNonNullableType:
case SyntaxKind.JSDocOptionalType:
return serializeTypeNode((<JSDocNullableType | JSDocNonNullableType | JSDocOptionalType>node).type);
default:
return Debug.failBadSyntaxKind(node);
+14
View File
@@ -6353,4 +6353,18 @@ namespace ts {
}) as HeritageClause | undefined;
return heritageClause?.token === SyntaxKind.ImplementsKeyword || heritageClause?.parent.kind === SyntaxKind.InterfaceDeclaration;
}
export function isIdentifierTypeReference(node: Node): node is TypeReferenceNode & { typeName: Identifier } {
return isTypeReferenceNode(node) && isIdentifier(node.typeName);
}
export function arrayIsHomogeneous<T>(array: readonly T[], comparer: EqualityComparer<T> = equateValues) {
if (array.length < 2) return true;
const first = array[0];
for (let i = 1, length = array.length; i < length; i++) {
const target = array[i];
if (!comparer(first, target)) return false;
}
return true;
}
}
+16 -154
View File
@@ -1,3 +1,10 @@
type FlatArray<Arr, Depth extends number> = {
"done": Arr,
"recur": Arr extends ReadonlyArray<infer InnerArr>
? FlatArray<InnerArr, [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20][Depth]>
: Arr
}[Depth extends -1 ? "done" : "recur"];
interface ReadonlyArray<T> {
/**
@@ -22,95 +29,11 @@ interface ReadonlyArray<T> {
*
* @param depth The maximum recursion depth
*/
flat<U>(this:
ReadonlyArray<U[][][][]> |
ReadonlyArray<ReadonlyArray<U[][][]>> |
ReadonlyArray<ReadonlyArray<U[][]>[]> |
ReadonlyArray<ReadonlyArray<U[]>[][]> |
ReadonlyArray<ReadonlyArray<U>[][][]> |
ReadonlyArray<ReadonlyArray<ReadonlyArray<U[][]>>> |
ReadonlyArray<ReadonlyArray<ReadonlyArray<U>[][]>> |
ReadonlyArray<ReadonlyArray<ReadonlyArray<U>>[][]> |
ReadonlyArray<ReadonlyArray<ReadonlyArray<U>[]>[]> |
ReadonlyArray<ReadonlyArray<ReadonlyArray<U[]>>[]> |
ReadonlyArray<ReadonlyArray<ReadonlyArray<U[]>[]>> |
ReadonlyArray<ReadonlyArray<ReadonlyArray<ReadonlyArray<U[]>>>> |
ReadonlyArray<ReadonlyArray<ReadonlyArray<ReadonlyArray<U>[]>>> |
ReadonlyArray<ReadonlyArray<ReadonlyArray<ReadonlyArray<U>>[]>> |
ReadonlyArray<ReadonlyArray<ReadonlyArray<ReadonlyArray<U>>>[]> |
ReadonlyArray<ReadonlyArray<ReadonlyArray<ReadonlyArray<ReadonlyArray<U>>>>>,
depth: 4): U[];
/**
* Returns a new array with all sub-array elements concatenated into it recursively up to the
* specified depth.
*
* @param depth The maximum recursion depth
*/
flat<U>(this:
ReadonlyArray<U[][][]> |
ReadonlyArray<ReadonlyArray<U>[][]> |
ReadonlyArray<ReadonlyArray<U[]>[]> |
ReadonlyArray<ReadonlyArray<U[][]>> |
ReadonlyArray<ReadonlyArray<ReadonlyArray<U[]>>> |
ReadonlyArray<ReadonlyArray<ReadonlyArray<U>[]>> |
ReadonlyArray<ReadonlyArray<ReadonlyArray<U>>[]> |
ReadonlyArray<ReadonlyArray<ReadonlyArray<ReadonlyArray<U>>>>,
depth: 3): U[];
/**
* Returns a new array with all sub-array elements concatenated into it recursively up to the
* specified depth.
*
* @param depth The maximum recursion depth
*/
flat<U>(this:
ReadonlyArray<U[][]> |
ReadonlyArray<ReadonlyArray<U[]>> |
ReadonlyArray<ReadonlyArray<U>[]> |
ReadonlyArray<ReadonlyArray<ReadonlyArray<U>>>,
depth: 2): U[];
/**
* Returns a new array with all sub-array elements concatenated into it recursively up to the
* specified depth.
*
* @param depth The maximum recursion depth
*/
flat<U>(this:
ReadonlyArray<U[]> |
ReadonlyArray<ReadonlyArray<U>>,
depth?: 1
): U[];
/**
* Returns a new array with all sub-array elements concatenated into it recursively up to the
* specified depth.
*
* @param depth The maximum recursion depth
*/
flat<U>(this:
ReadonlyArray<U>,
depth: 0
): U[];
/**
* Returns a new array with all sub-array elements concatenated into it recursively up to the
* specified depth. If no depth is provided, flat method defaults to the depth of 1.
*
* @param depth The maximum recursion depth
*/
flat<U>(depth?: number): any[];
}
flat<A, D extends number = 1>(
this: A,
depth?: D
): FlatArray<A, D>[]
}
interface Array<T> {
@@ -135,69 +58,8 @@ interface Array<T> {
*
* @param depth The maximum recursion depth
*/
flat<U>(this: U[][][][][][][][], depth: 7): U[];
/**
* Returns a new array with all sub-array elements concatenated into it recursively up to the
* specified depth.
*
* @param depth The maximum recursion depth
*/
flat<U>(this: U[][][][][][][], depth: 6): U[];
/**
* Returns a new array with all sub-array elements concatenated into it recursively up to the
* specified depth.
*
* @param depth The maximum recursion depth
*/
flat<U>(this: U[][][][][][], depth: 5): U[];
/**
* Returns a new array with all sub-array elements concatenated into it recursively up to the
* specified depth.
*
* @param depth The maximum recursion depth
*/
flat<U>(this: U[][][][][], depth: 4): U[];
/**
* Returns a new array with all sub-array elements concatenated into it recursively up to the
* specified depth.
*
* @param depth The maximum recursion depth
*/
flat<U>(this: U[][][][], depth: 3): U[];
/**
* Returns a new array with all sub-array elements concatenated into it recursively up to the
* specified depth.
*
* @param depth The maximum recursion depth
*/
flat<U>(this: U[][][], depth: 2): U[];
/**
* Returns a new array with all sub-array elements concatenated into it recursively up to the
* specified depth.
*
* @param depth The maximum recursion depth
*/
flat<U>(this: U[][], depth?: 1): U[];
/**
* Returns a new array with all sub-array elements concatenated into it recursively up to the
* specified depth.
*
* @param depth The maximum recursion depth
*/
flat<U>(this: U[], depth: 0): U[];
/**
* Returns a new array with all sub-array elements concatenated into it recursively up to the
* specified depth. If no depth is provided, flat method defaults to the depth of 1.
*
* @param depth The maximum recursion depth
*/
flat<U>(depth?: number): any[];
flat<A, D extends number = 1>(
this: A,
depth?: D
): FlatArray<A, D>[]
}
+1 -1
View File
@@ -211,7 +211,7 @@ namespace ts.codefix {
reference;
const diagnostic = find(diagnostics, diagnostic =>
diagnostic.start === errorNode.getStart(sourceFile) &&
diagnostic.start + diagnostic.length! === errorNode.getEnd());
(diagnostic.start + diagnostic.length!) === errorNode.getEnd());
return diagnostic && contains(errorCodes, diagnostic.code) ||
// A Promise is usually not correct in a binary expression (its not valid
@@ -46,6 +46,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
const { isStatic, isReadonly, fieldName, accessorName, originalName, type, container, declaration, renameAccessor } = fieldInfo;
suppressLeadingAndTrailingTrivia(fieldName);
suppressLeadingAndTrailingTrivia(accessorName);
suppressLeadingAndTrailingTrivia(declaration);
suppressLeadingAndTrailingTrivia(container);
@@ -5,23 +5,20 @@ tests/cases/compiler/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.t
Type '"text" | "email"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"] & ChannelOfType<T, EmailChannel>["type"]'.
Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"] & ChannelOfType<T, EmailChannel>["type"]'.
Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
Type '"text"' is not assignable to type 'T & "text"'.
Type '"text"' is not assignable to type 'T'.
'"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'.
Type 'T' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
Type '"text" | "email"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
Type '"text"' is not assignable to type 'T & "text"'.
Type '"text"' is not assignable to type 'T'.
'"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'.
Type 'T' is not assignable to type 'T & "text"'.
Type '"text" | "email"' is not assignable to type 'T & "text"'.
Type '"text"' is not assignable to type 'T & "text"'.
Type '"text"' is not assignable to type 'T'.
'"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'.
Type 'T' is not assignable to type '"text"'.
Type '"text" | "email"' is not assignable to type '"text"'.
Type '"email"' is not assignable to type '"text"'.
Type 'T' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
Type '"text" | "email"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
Type '"text"' is not assignable to type 'T & "text"'.
Type '"text"' is not assignable to type 'T'.
'"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'.
Type 'T' is not assignable to type 'T & "text"'.
Type '"text" | "email"' is not assignable to type 'T & "text"'.
Type '"text"' is not assignable to type 'T & "text"'.
Type '"text"' is not assignable to type 'T'.
'"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'.
Type 'T' is not assignable to type '"text"'.
Type '"text" | "email"' is not assignable to type '"text"'.
Type '"email"' is not assignable to type '"text"'.
==== tests/cases/compiler/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.ts (1 errors) ====
@@ -66,23 +63,20 @@ tests/cases/compiler/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.t
!!! error TS2322: Type '"text" | "email"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"] & ChannelOfType<T, EmailChannel>["type"]'.
!!! error TS2322: Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"] & ChannelOfType<T, EmailChannel>["type"]'.
!!! error TS2322: Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
!!! error TS2322: Type '"text"' is not assignable to type 'T & "text"'.
!!! error TS2322: Type '"text"' is not assignable to type 'T'.
!!! error TS2322: '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'.
!!! error TS2322: Type 'T' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
!!! error TS2322: Type '"text" | "email"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
!!! error TS2322: Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
!!! error TS2322: Type '"text"' is not assignable to type 'T & "text"'.
!!! error TS2322: Type '"text"' is not assignable to type 'T'.
!!! error TS2322: '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'.
!!! error TS2322: Type 'T' is not assignable to type 'T & "text"'.
!!! error TS2322: Type '"text" | "email"' is not assignable to type 'T & "text"'.
!!! error TS2322: Type '"text"' is not assignable to type 'T & "text"'.
!!! error TS2322: Type '"text"' is not assignable to type 'T'.
!!! error TS2322: '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'.
!!! error TS2322: Type 'T' is not assignable to type '"text"'.
!!! error TS2322: Type '"text" | "email"' is not assignable to type '"text"'.
!!! error TS2322: Type '"email"' is not assignable to type '"text"'.
!!! error TS2322: Type 'T' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
!!! error TS2322: Type '"text" | "email"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
!!! error TS2322: Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
!!! error TS2322: Type '"text"' is not assignable to type 'T & "text"'.
!!! error TS2322: Type '"text"' is not assignable to type 'T'.
!!! error TS2322: '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'.
!!! error TS2322: Type 'T' is not assignable to type 'T & "text"'.
!!! error TS2322: Type '"text" | "email"' is not assignable to type 'T & "text"'.
!!! error TS2322: Type '"text"' is not assignable to type 'T & "text"'.
!!! error TS2322: Type '"text"' is not assignable to type 'T'.
!!! error TS2322: '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'.
!!! error TS2322: Type 'T' is not assignable to type '"text"'.
!!! error TS2322: Type '"text" | "email"' is not assignable to type '"text"'.
!!! error TS2322: Type '"email"' is not assignable to type '"text"'.
}
const newTextChannel = makeNewChannel('text');
@@ -0,0 +1,22 @@
tests/cases/conformance/decorators/decoratorMetadata-jsdoc.ts(5,9): error TS8020: JSDoc types can only be used inside documentation comments.
tests/cases/conformance/decorators/decoratorMetadata-jsdoc.ts(7,9): error TS8020: JSDoc types can only be used inside documentation comments.
tests/cases/conformance/decorators/decoratorMetadata-jsdoc.ts(9,9): error TS8020: JSDoc types can only be used inside documentation comments.
==== tests/cases/conformance/decorators/decoratorMetadata-jsdoc.ts (3 errors) ====
declare var decorator: any;
class X {
@decorator()
a?: string?;
~~~~~~~
!!! error TS8020: JSDoc types can only be used inside documentation comments.
@decorator()
b?: string!;
~~~~~~~
!!! error TS8020: JSDoc types can only be used inside documentation comments.
@decorator()
c?: *;
~
!!! error TS8020: JSDoc types can only be used inside documentation comments.
}
@@ -0,0 +1,39 @@
//// [decoratorMetadata-jsdoc.ts]
declare var decorator: any;
class X {
@decorator()
a?: string?;
@decorator()
b?: string!;
@decorator()
c?: *;
}
//// [decoratorMetadata-jsdoc.js]
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var X = /** @class */ (function () {
function X() {
}
__decorate([
decorator(),
__metadata("design:type", String)
], X.prototype, "a", void 0);
__decorate([
decorator(),
__metadata("design:type", String)
], X.prototype, "b", void 0);
__decorate([
decorator(),
__metadata("design:type", Object)
], X.prototype, "c", void 0);
return X;
}());
@@ -0,0 +1,25 @@
=== tests/cases/conformance/decorators/decoratorMetadata-jsdoc.ts ===
declare var decorator: any;
>decorator : Symbol(decorator, Decl(decoratorMetadata-jsdoc.ts, 0, 11))
class X {
>X : Symbol(X, Decl(decoratorMetadata-jsdoc.ts, 0, 27))
@decorator()
>decorator : Symbol(decorator, Decl(decoratorMetadata-jsdoc.ts, 0, 11))
a?: string?;
>a : Symbol(X.a, Decl(decoratorMetadata-jsdoc.ts, 2, 9))
@decorator()
>decorator : Symbol(decorator, Decl(decoratorMetadata-jsdoc.ts, 0, 11))
b?: string!;
>b : Symbol(X.b, Decl(decoratorMetadata-jsdoc.ts, 4, 16))
@decorator()
>decorator : Symbol(decorator, Decl(decoratorMetadata-jsdoc.ts, 0, 11))
c?: *;
>c : Symbol(X.c, Decl(decoratorMetadata-jsdoc.ts, 6, 16))
}
@@ -0,0 +1,28 @@
=== tests/cases/conformance/decorators/decoratorMetadata-jsdoc.ts ===
declare var decorator: any;
>decorator : any
class X {
>X : X
@decorator()
>decorator() : any
>decorator : any
a?: string?;
>a : string
@decorator()
>decorator() : any
>decorator : any
b?: string!;
>b : string
@decorator()
>decorator() : any
>decorator : any
c?: *;
>c : any
}
@@ -0,0 +1,18 @@
//// [forwardRefInTypeDeclaration.ts]
// forward ref ignored in a typeof
declare let s: typeof s1;
const s1 = "x";
// ignored anywhere in an interface (#35947)
interface Foo2 { [s2]: number; }
const s2 = "x";
// or in a type definition
type Foo3 = { [s3]: number; }
const s3 = "x";
//// [forwardRefInTypeDeclaration.js]
var s1 = "x";
var s2 = "x";
var s3 = "x";
@@ -0,0 +1,27 @@
=== tests/cases/compiler/forwardRefInTypeDeclaration.ts ===
// forward ref ignored in a typeof
declare let s: typeof s1;
>s : Symbol(s, Decl(forwardRefInTypeDeclaration.ts, 1, 11))
>s1 : Symbol(s1, Decl(forwardRefInTypeDeclaration.ts, 2, 5))
const s1 = "x";
>s1 : Symbol(s1, Decl(forwardRefInTypeDeclaration.ts, 2, 5))
// ignored anywhere in an interface (#35947)
interface Foo2 { [s2]: number; }
>Foo2 : Symbol(Foo2, Decl(forwardRefInTypeDeclaration.ts, 2, 15))
>[s2] : Symbol(Foo2[s2], Decl(forwardRefInTypeDeclaration.ts, 5, 16))
>s2 : Symbol(s2, Decl(forwardRefInTypeDeclaration.ts, 6, 5))
const s2 = "x";
>s2 : Symbol(s2, Decl(forwardRefInTypeDeclaration.ts, 6, 5))
// or in a type definition
type Foo3 = { [s3]: number; }
>Foo3 : Symbol(Foo3, Decl(forwardRefInTypeDeclaration.ts, 6, 15))
>[s3] : Symbol([s3], Decl(forwardRefInTypeDeclaration.ts, 9, 13))
>s3 : Symbol(s3, Decl(forwardRefInTypeDeclaration.ts, 10, 5))
const s3 = "x";
>s3 : Symbol(s3, Decl(forwardRefInTypeDeclaration.ts, 10, 5))
@@ -0,0 +1,29 @@
=== tests/cases/compiler/forwardRefInTypeDeclaration.ts ===
// forward ref ignored in a typeof
declare let s: typeof s1;
>s : "x"
>s1 : "x"
const s1 = "x";
>s1 : "x"
>"x" : "x"
// ignored anywhere in an interface (#35947)
interface Foo2 { [s2]: number; }
>[s2] : number
>s2 : "x"
const s2 = "x";
>s2 : "x"
>"x" : "x"
// or in a type definition
type Foo3 = { [s3]: number; }
>Foo3 : Foo3
>[s3] : number
>s3 : "x"
const s3 = "x";
>s3 : "x"
>"x" : "x"
@@ -0,0 +1,23 @@
//// [instantiateTemplateTagTypeParameterOnVariableStatement.js]
/**
* @template T
* @param {T} a
* @returns {(b: T) => T}
*/
const seq = a => b => b;
const text1 = "hello";
const text2 = "world";
/** @type {string} */
var text3 = seq(text1)(text2);
//// [instantiateTemplateTagTypeParameterOnVariableStatement.d.ts]
declare function seq<T>(a: T): (b: T) => T;
declare const text1: "hello";
declare const text2: "world";
/** @type {string} */
declare var text3: string;
@@ -0,0 +1,25 @@
=== tests/cases/conformance/jsdoc/instantiateTemplateTagTypeParameterOnVariableStatement.js ===
/**
* @template T
* @param {T} a
* @returns {(b: T) => T}
*/
const seq = a => b => b;
>seq : Symbol(seq, Decl(instantiateTemplateTagTypeParameterOnVariableStatement.js, 5, 5))
>a : Symbol(a, Decl(instantiateTemplateTagTypeParameterOnVariableStatement.js, 5, 11))
>b : Symbol(b, Decl(instantiateTemplateTagTypeParameterOnVariableStatement.js, 5, 16))
>b : Symbol(b, Decl(instantiateTemplateTagTypeParameterOnVariableStatement.js, 5, 16))
const text1 = "hello";
>text1 : Symbol(text1, Decl(instantiateTemplateTagTypeParameterOnVariableStatement.js, 7, 5))
const text2 = "world";
>text2 : Symbol(text2, Decl(instantiateTemplateTagTypeParameterOnVariableStatement.js, 8, 5))
/** @type {string} */
var text3 = seq(text1)(text2);
>text3 : Symbol(text3, Decl(instantiateTemplateTagTypeParameterOnVariableStatement.js, 11, 3))
>seq : Symbol(seq, Decl(instantiateTemplateTagTypeParameterOnVariableStatement.js, 5, 5))
>text1 : Symbol(text1, Decl(instantiateTemplateTagTypeParameterOnVariableStatement.js, 7, 5))
>text2 : Symbol(text2, Decl(instantiateTemplateTagTypeParameterOnVariableStatement.js, 8, 5))
@@ -0,0 +1,31 @@
=== tests/cases/conformance/jsdoc/instantiateTemplateTagTypeParameterOnVariableStatement.js ===
/**
* @template T
* @param {T} a
* @returns {(b: T) => T}
*/
const seq = a => b => b;
>seq : <T>(a: T) => (b: T) => T
>a => b => b : <T>(a: T) => (b: T) => T
>a : T
>b => b : (b: T) => T
>b : T
>b : T
const text1 = "hello";
>text1 : "hello"
>"hello" : "hello"
const text2 = "world";
>text2 : "world"
>"world" : "world"
/** @type {string} */
var text3 = seq(text1)(text2);
>text3 : string
>seq(text1)(text2) : string
>seq(text1) : (b: string) => string
>seq : <T>(a: T) => (b: T) => T
>text1 : "hello"
>text2 : "world"
@@ -0,0 +1,46 @@
tests/cases/compiler/intersectionPropertyCheck.ts(1,68): error TS2322: Type '{ x: string; y: number; }' is not assignable to type '{ x: string; }'.
Object literal may only specify known properties, and 'y' does not exist in type '{ x: string; }'.
tests/cases/compiler/intersectionPropertyCheck.ts(4,5): error TS2322: Type '{ a: { y: string; }; }' is not assignable to type '{ a?: { x?: number | undefined; } | undefined; } & { c?: string | undefined; }'.
Types of property 'a' are incompatible.
Type '{ y: string; }' has no properties in common with type '{ x?: number | undefined; }'.
tests/cases/compiler/intersectionPropertyCheck.ts(7,3): error TS2322: Type 'T & { a: boolean; }' is not assignable to type '{ a?: string | undefined; }'.
Types of property 'a' are incompatible.
Type 'boolean' is not assignable to type 'string | undefined'.
tests/cases/compiler/intersectionPropertyCheck.ts(17,22): error TS2322: Type 'true' is not assignable to type 'string[] | undefined'.
==== tests/cases/compiler/intersectionPropertyCheck.ts (4 errors) ====
let obj: { a: { x: string } } & { c: number } = { a: { x: 'hello', y: 2 }, c: 5 }; // Nested excess property
~~~~
!!! error TS2322: Type '{ x: string; y: number; }' is not assignable to type '{ x: string; }'.
!!! error TS2322: Object literal may only specify known properties, and 'y' does not exist in type '{ x: string; }'.
!!! related TS6500 tests/cases/compiler/intersectionPropertyCheck.ts:1:12: The expected type comes from property 'a' which is declared here on type '{ a: { x: string; }; } & { c: number; }'
declare let wrong: { a: { y: string } };
let weak: { a?: { x?: number } } & { c?: string } = wrong; // Nested weak object type
~~~~
!!! error TS2322: Type '{ a: { y: string; }; }' is not assignable to type '{ a?: { x?: number | undefined; } | undefined; } & { c?: string | undefined; }'.
!!! error TS2322: Types of property 'a' are incompatible.
!!! error TS2322: Type '{ y: string; }' has no properties in common with type '{ x?: number | undefined; }'.
function foo<T extends object>(x: { a?: string }, y: T & { a: boolean }) {
x = y; // Mismatched property in source intersection
~
!!! error TS2322: Type 'T & { a: boolean; }' is not assignable to type '{ a?: string | undefined; }'.
!!! error TS2322: Types of property 'a' are incompatible.
!!! error TS2322: Type 'boolean' is not assignable to type 'string | undefined'.
}
// Repro from #36637
interface Test {
readonly hi?: string[]
}
function test<T extends object>(value: T): Test {
return { ...value, hi: true }
~~
!!! error TS2322: Type 'true' is not assignable to type 'string[] | undefined'.
!!! related TS6500 tests/cases/compiler/intersectionPropertyCheck.ts:13:12: The expected type comes from property 'hi' which is declared here on type 'Test'
}
@@ -0,0 +1,42 @@
//// [intersectionPropertyCheck.ts]
let obj: { a: { x: string } } & { c: number } = { a: { x: 'hello', y: 2 }, c: 5 }; // Nested excess property
declare let wrong: { a: { y: string } };
let weak: { a?: { x?: number } } & { c?: string } = wrong; // Nested weak object type
function foo<T extends object>(x: { a?: string }, y: T & { a: boolean }) {
x = y; // Mismatched property in source intersection
}
// Repro from #36637
interface Test {
readonly hi?: string[]
}
function test<T extends object>(value: T): Test {
return { ...value, hi: true }
}
//// [intersectionPropertyCheck.js]
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var obj = { a: { x: 'hello', y: 2 }, c: 5 }; // Nested excess property
var weak = wrong; // Nested weak object type
function foo(x, y) {
x = y; // Mismatched property in source intersection
}
function test(value) {
return __assign(__assign({}, value), { hi: true });
}
@@ -0,0 +1,58 @@
=== tests/cases/compiler/intersectionPropertyCheck.ts ===
let obj: { a: { x: string } } & { c: number } = { a: { x: 'hello', y: 2 }, c: 5 }; // Nested excess property
>obj : Symbol(obj, Decl(intersectionPropertyCheck.ts, 0, 3))
>a : Symbol(a, Decl(intersectionPropertyCheck.ts, 0, 10))
>x : Symbol(x, Decl(intersectionPropertyCheck.ts, 0, 15))
>c : Symbol(c, Decl(intersectionPropertyCheck.ts, 0, 33))
>a : Symbol(a, Decl(intersectionPropertyCheck.ts, 0, 49))
>x : Symbol(x, Decl(intersectionPropertyCheck.ts, 0, 54))
>y : Symbol(y, Decl(intersectionPropertyCheck.ts, 0, 66))
>c : Symbol(c, Decl(intersectionPropertyCheck.ts, 0, 74))
declare let wrong: { a: { y: string } };
>wrong : Symbol(wrong, Decl(intersectionPropertyCheck.ts, 2, 11))
>a : Symbol(a, Decl(intersectionPropertyCheck.ts, 2, 20))
>y : Symbol(y, Decl(intersectionPropertyCheck.ts, 2, 25))
let weak: { a?: { x?: number } } & { c?: string } = wrong; // Nested weak object type
>weak : Symbol(weak, Decl(intersectionPropertyCheck.ts, 3, 3))
>a : Symbol(a, Decl(intersectionPropertyCheck.ts, 3, 11))
>x : Symbol(x, Decl(intersectionPropertyCheck.ts, 3, 17))
>c : Symbol(c, Decl(intersectionPropertyCheck.ts, 3, 36))
>wrong : Symbol(wrong, Decl(intersectionPropertyCheck.ts, 2, 11))
function foo<T extends object>(x: { a?: string }, y: T & { a: boolean }) {
>foo : Symbol(foo, Decl(intersectionPropertyCheck.ts, 3, 58))
>T : Symbol(T, Decl(intersectionPropertyCheck.ts, 5, 13))
>x : Symbol(x, Decl(intersectionPropertyCheck.ts, 5, 31))
>a : Symbol(a, Decl(intersectionPropertyCheck.ts, 5, 35))
>y : Symbol(y, Decl(intersectionPropertyCheck.ts, 5, 49))
>T : Symbol(T, Decl(intersectionPropertyCheck.ts, 5, 13))
>a : Symbol(a, Decl(intersectionPropertyCheck.ts, 5, 58))
x = y; // Mismatched property in source intersection
>x : Symbol(x, Decl(intersectionPropertyCheck.ts, 5, 31))
>y : Symbol(y, Decl(intersectionPropertyCheck.ts, 5, 49))
}
// Repro from #36637
interface Test {
>Test : Symbol(Test, Decl(intersectionPropertyCheck.ts, 7, 1))
readonly hi?: string[]
>hi : Symbol(Test.hi, Decl(intersectionPropertyCheck.ts, 11, 16))
}
function test<T extends object>(value: T): Test {
>test : Symbol(test, Decl(intersectionPropertyCheck.ts, 13, 1))
>T : Symbol(T, Decl(intersectionPropertyCheck.ts, 15, 14))
>value : Symbol(value, Decl(intersectionPropertyCheck.ts, 15, 32))
>T : Symbol(T, Decl(intersectionPropertyCheck.ts, 15, 14))
>Test : Symbol(Test, Decl(intersectionPropertyCheck.ts, 7, 1))
return { ...value, hi: true }
>value : Symbol(value, Decl(intersectionPropertyCheck.ts, 15, 32))
>hi : Symbol(hi, Decl(intersectionPropertyCheck.ts, 16, 20))
}
@@ -0,0 +1,59 @@
=== tests/cases/compiler/intersectionPropertyCheck.ts ===
let obj: { a: { x: string } } & { c: number } = { a: { x: 'hello', y: 2 }, c: 5 }; // Nested excess property
>obj : { a: { x: string;}; } & { c: number; }
>a : { x: string; }
>x : string
>c : number
>{ a: { x: 'hello', y: 2 }, c: 5 } : { a: { x: string; y: number; }; c: number; }
>a : { x: string; y: number; }
>{ x: 'hello', y: 2 } : { x: string; y: number; }
>x : string
>'hello' : "hello"
>y : number
>2 : 2
>c : number
>5 : 5
declare let wrong: { a: { y: string } };
>wrong : { a: { y: string;}; }
>a : { y: string; }
>y : string
let weak: { a?: { x?: number } } & { c?: string } = wrong; // Nested weak object type
>weak : { a?: { x?: number | undefined; } | undefined; } & { c?: string | undefined; }
>a : { x?: number | undefined; } | undefined
>x : number | undefined
>c : string | undefined
>wrong : { a: { y: string; }; }
function foo<T extends object>(x: { a?: string }, y: T & { a: boolean }) {
>foo : <T extends object>(x: { a?: string;}, y: T & { a: boolean;}) => void
>x : { a?: string | undefined; }
>a : string | undefined
>y : T & { a: boolean; }
>a : boolean
x = y; // Mismatched property in source intersection
>x = y : T & { a: boolean; }
>x : { a?: string | undefined; }
>y : T & { a: boolean; }
}
// Repro from #36637
interface Test {
readonly hi?: string[]
>hi : string[] | undefined
}
function test<T extends object>(value: T): Test {
>test : <T extends object>(value: T) => Test
>value : T
return { ...value, hi: true }
>{ ...value, hi: true } : T & { hi: boolean; }
>value : T
>hi : boolean
>true : true
}
@@ -0,0 +1,29 @@
tests/cases/compiler/namespaceDisambiguationInUnion.ts(10,7): error TS2322: Type '{ type: string; }' is not assignable to type 'Foo.Yep | Bar.Yep'.
Type '{ type: string; }' is not assignable to type 'Yep'.
Types of property 'type' are incompatible.
Type 'string' is not assignable to type '"bar.yep"'.
tests/cases/compiler/namespaceDisambiguationInUnion.ts(13,7): error TS2739: Type '{ type: string; }[]' is missing the following properties from type '[Foo.Yep, Bar.Yep]': 0, 1
==== tests/cases/compiler/namespaceDisambiguationInUnion.ts (2 errors) ====
namespace Foo {
export type Yep = { type: "foo.yep" };
}
namespace Bar {
export type Yep = { type: "bar.yep" };
}
const x = { type: "wat.nup" };
const val1: Foo.Yep | Bar.Yep = x;
~~~~
!!! error TS2322: Type '{ type: string; }' is not assignable to type 'Foo.Yep | Bar.Yep'.
!!! error TS2322: Type '{ type: string; }' is not assignable to type 'Yep'.
!!! error TS2322: Types of property 'type' are incompatible.
!!! error TS2322: Type 'string' is not assignable to type '"bar.yep"'.
const y = [{ type: "a" }, { type: "b" }];
const val2: [Foo.Yep, Bar.Yep] = y;
~~~~
!!! error TS2739: Type '{ type: string; }[]' is missing the following properties from type '[Foo.Yep, Bar.Yep]': 0, 1
@@ -0,0 +1,21 @@
//// [namespaceDisambiguationInUnion.ts]
namespace Foo {
export type Yep = { type: "foo.yep" };
}
namespace Bar {
export type Yep = { type: "bar.yep" };
}
const x = { type: "wat.nup" };
const val1: Foo.Yep | Bar.Yep = x;
const y = [{ type: "a" }, { type: "b" }];
const val2: [Foo.Yep, Bar.Yep] = y;
//// [namespaceDisambiguationInUnion.js]
var x = { type: "wat.nup" };
var val1 = x;
var y = [{ type: "a" }, { type: "b" }];
var val2 = y;
@@ -0,0 +1,42 @@
=== tests/cases/compiler/namespaceDisambiguationInUnion.ts ===
namespace Foo {
>Foo : Symbol(Foo, Decl(namespaceDisambiguationInUnion.ts, 0, 0))
export type Yep = { type: "foo.yep" };
>Yep : Symbol(Yep, Decl(namespaceDisambiguationInUnion.ts, 0, 15))
>type : Symbol(type, Decl(namespaceDisambiguationInUnion.ts, 1, 21))
}
namespace Bar {
>Bar : Symbol(Bar, Decl(namespaceDisambiguationInUnion.ts, 2, 1))
export type Yep = { type: "bar.yep" };
>Yep : Symbol(Yep, Decl(namespaceDisambiguationInUnion.ts, 4, 15))
>type : Symbol(type, Decl(namespaceDisambiguationInUnion.ts, 5, 21))
}
const x = { type: "wat.nup" };
>x : Symbol(x, Decl(namespaceDisambiguationInUnion.ts, 8, 5))
>type : Symbol(type, Decl(namespaceDisambiguationInUnion.ts, 8, 11))
const val1: Foo.Yep | Bar.Yep = x;
>val1 : Symbol(val1, Decl(namespaceDisambiguationInUnion.ts, 9, 5))
>Foo : Symbol(Foo, Decl(namespaceDisambiguationInUnion.ts, 0, 0))
>Yep : Symbol(Foo.Yep, Decl(namespaceDisambiguationInUnion.ts, 0, 15))
>Bar : Symbol(Bar, Decl(namespaceDisambiguationInUnion.ts, 2, 1))
>Yep : Symbol(Bar.Yep, Decl(namespaceDisambiguationInUnion.ts, 4, 15))
>x : Symbol(x, Decl(namespaceDisambiguationInUnion.ts, 8, 5))
const y = [{ type: "a" }, { type: "b" }];
>y : Symbol(y, Decl(namespaceDisambiguationInUnion.ts, 11, 5))
>type : Symbol(type, Decl(namespaceDisambiguationInUnion.ts, 11, 12))
>type : Symbol(type, Decl(namespaceDisambiguationInUnion.ts, 11, 27))
const val2: [Foo.Yep, Bar.Yep] = y;
>val2 : Symbol(val2, Decl(namespaceDisambiguationInUnion.ts, 12, 5))
>Foo : Symbol(Foo, Decl(namespaceDisambiguationInUnion.ts, 0, 0))
>Yep : Symbol(Foo.Yep, Decl(namespaceDisambiguationInUnion.ts, 0, 15))
>Bar : Symbol(Bar, Decl(namespaceDisambiguationInUnion.ts, 2, 1))
>Yep : Symbol(Bar.Yep, Decl(namespaceDisambiguationInUnion.ts, 4, 15))
>y : Symbol(y, Decl(namespaceDisambiguationInUnion.ts, 11, 5))
@@ -0,0 +1,41 @@
=== tests/cases/compiler/namespaceDisambiguationInUnion.ts ===
namespace Foo {
export type Yep = { type: "foo.yep" };
>Yep : Yep
>type : "foo.yep"
}
namespace Bar {
export type Yep = { type: "bar.yep" };
>Yep : Yep
>type : "bar.yep"
}
const x = { type: "wat.nup" };
>x : { type: string; }
>{ type: "wat.nup" } : { type: string; }
>type : string
>"wat.nup" : "wat.nup"
const val1: Foo.Yep | Bar.Yep = x;
>val1 : Foo.Yep | Bar.Yep
>Foo : any
>Bar : any
>x : { type: string; }
const y = [{ type: "a" }, { type: "b" }];
>y : { type: string; }[]
>[{ type: "a" }, { type: "b" }] : { type: string; }[]
>{ type: "a" } : { type: string; }
>type : string
>"a" : "a"
>{ type: "b" } : { type: string; }
>type : string
>"b" : "b"
const val2: [Foo.Yep, Bar.Yep] = y;
>val2 : [Foo.Yep, Bar.Yep]
>Foo : any
>Bar : any
>y : { type: string; }[]
@@ -63,6 +63,7 @@
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
@@ -63,6 +63,7 @@
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
@@ -63,6 +63,7 @@
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
@@ -63,6 +63,7 @@
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
},
"files": [
@@ -63,6 +63,7 @@
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
@@ -63,6 +63,7 @@
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
@@ -63,6 +63,7 @@
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
@@ -63,6 +63,7 @@
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
@@ -85,6 +85,7 @@ interface Array<T> { length: number; [n: number]: T; }
/* Advanced Options */
"declarationDir": "decls", /* Output directory for generated declaration files. */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
@@ -127,7 +128,7 @@ Output::
Program root files: ["/user/username/projects/myproject/file1.ts","/user/username/projects/myproject/src/file2.ts"]
Program options: {"target":1,"module":2,"declaration":true,"strict":true,"esModuleInterop":true,"declarationDir":"/user/username/projects/myproject/decls","forceConsistentCasingInFileNames":true,"watch":true,"project":"/user/username/projects/myproject/tsconfig.json","configFilePath":"/user/username/projects/myproject/tsconfig.json"}
Program options: {"target":1,"module":2,"declaration":true,"strict":true,"esModuleInterop":true,"declarationDir":"/user/username/projects/myproject/decls","skipLibCheck":true,"forceConsistentCasingInFileNames":true,"watch":true,"project":"/user/username/projects/myproject/tsconfig.json","configFilePath":"/user/username/projects/myproject/tsconfig.json"}
Program files::
/a/lib/lib.d.ts
/user/username/projects/myproject/file1.ts
@@ -85,6 +85,7 @@ interface Array<T> { length: number; [n: number]: T; }
/* Advanced Options */
"declarationDir": "decls", /* Output directory for generated declaration files. */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
@@ -127,7 +128,7 @@ Output::
Program root files: ["/user/username/projects/myproject/file1.ts","/user/username/projects/myproject/src/file2.ts"]
Program options: {"target":1,"module":2,"declaration":true,"outDir":"/user/username/projects/myproject/build","strict":true,"esModuleInterop":true,"declarationDir":"/user/username/projects/myproject/decls","forceConsistentCasingInFileNames":true,"watch":true,"project":"/user/username/projects/myproject/tsconfig.json","configFilePath":"/user/username/projects/myproject/tsconfig.json"}
Program options: {"target":1,"module":2,"declaration":true,"outDir":"/user/username/projects/myproject/build","strict":true,"esModuleInterop":true,"declarationDir":"/user/username/projects/myproject/decls","skipLibCheck":true,"forceConsistentCasingInFileNames":true,"watch":true,"project":"/user/username/projects/myproject/tsconfig.json","configFilePath":"/user/username/projects/myproject/tsconfig.json"}
Program files::
/a/lib/lib.d.ts
/user/username/projects/myproject/file1.ts
@@ -84,6 +84,7 @@ interface Array<T> { length: number; [n: number]: T; }
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
@@ -118,7 +119,7 @@ Output::
Program root files: ["/user/username/projects/myproject/file1.ts","/user/username/projects/myproject/src/file2.ts"]
Program options: {"target":1,"module":2,"outDir":"/user/username/projects/myproject/build","strict":true,"esModuleInterop":true,"forceConsistentCasingInFileNames":true,"watch":true,"project":"/user/username/projects/myproject/tsconfig.json","configFilePath":"/user/username/projects/myproject/tsconfig.json"}
Program options: {"target":1,"module":2,"outDir":"/user/username/projects/myproject/build","strict":true,"esModuleInterop":true,"skipLibCheck":true,"forceConsistentCasingInFileNames":true,"watch":true,"project":"/user/username/projects/myproject/tsconfig.json","configFilePath":"/user/username/projects/myproject/tsconfig.json"}
Program files::
/a/lib/lib.d.ts
/user/username/projects/myproject/file1.ts
@@ -84,6 +84,7 @@ interface Array<T> { length: number; [n: number]: T; }
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
@@ -115,7 +116,7 @@ Output::
Program root files: ["/user/username/projects/myproject/file1.ts","/user/username/projects/myproject/src/file2.ts"]
Program options: {"target":1,"module":2,"outFile":"/user/username/projects/myproject/build/outFile.js","strict":true,"esModuleInterop":true,"forceConsistentCasingInFileNames":true,"watch":true,"project":"/user/username/projects/myproject/tsconfig.json","configFilePath":"/user/username/projects/myproject/tsconfig.json"}
Program options: {"target":1,"module":2,"outFile":"/user/username/projects/myproject/build/outFile.js","strict":true,"esModuleInterop":true,"skipLibCheck":true,"forceConsistentCasingInFileNames":true,"watch":true,"project":"/user/username/projects/myproject/tsconfig.json","configFilePath":"/user/username/projects/myproject/tsconfig.json"}
Program files::
/a/lib/lib.d.ts
/user/username/projects/myproject/file1.ts
@@ -84,6 +84,7 @@ interface Array<T> { length: number; [n: number]: T; }
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
@@ -118,7 +119,7 @@ Output::
Program root files: ["/user/username/projects/myproject/file1.ts","/user/username/projects/myproject/src/file2.ts"]
Program options: {"target":1,"module":2,"strict":true,"esModuleInterop":true,"forceConsistentCasingInFileNames":true,"watch":true,"project":"/user/username/projects/myproject/tsconfig.json","configFilePath":"/user/username/projects/myproject/tsconfig.json"}
Program options: {"target":1,"module":2,"strict":true,"esModuleInterop":true,"skipLibCheck":true,"forceConsistentCasingInFileNames":true,"watch":true,"project":"/user/username/projects/myproject/tsconfig.json","configFilePath":"/user/username/projects/myproject/tsconfig.json"}
Program files::
/a/lib/lib.d.ts
/user/username/projects/myproject/file1.ts
@@ -5,8 +5,9 @@ tests/cases/compiler/weakType.ts(18,13): error TS2559: Type '12' has no properti
tests/cases/compiler/weakType.ts(19,13): error TS2559: Type '"completely wrong"' has no properties in common with type 'Settings'.
tests/cases/compiler/weakType.ts(20,13): error TS2559: Type 'false' has no properties in common with type 'Settings'.
tests/cases/compiler/weakType.ts(37,18): error TS2559: Type '{ error?: number; }' has no properties in common with type 'ChangeOptions'.
tests/cases/compiler/weakType.ts(62,5): error TS2326: Types of property 'properties' are incompatible.
Type '{ wrong: string; }' has no properties in common with type '{ b?: number; }'.
tests/cases/compiler/weakType.ts(62,5): error TS2322: Type '{ properties: { wrong: string; }; }' is not assignable to type 'Weak & Spoiler'.
Types of property 'properties' are incompatible.
Type '{ wrong: string; }' has no properties in common with type '{ b?: number; }'.
==== tests/cases/compiler/weakType.ts (8 errors) ====
@@ -90,7 +91,8 @@ tests/cases/compiler/weakType.ts(62,5): error TS2326: Types of property 'propert
}
let weak: Weak & Spoiler = propertiesWrong
~~~~
!!! error TS2326: Types of property 'properties' are incompatible.
!!! error TS2326: Type '{ wrong: string; }' has no properties in common with type '{ b?: number; }'.
!!! error TS2322: Type '{ properties: { wrong: string; }; }' is not assignable to type 'Weak & Spoiler'.
!!! error TS2322: Types of property 'properties' are incompatible.
!!! error TS2322: Type '{ wrong: string; }' has no properties in common with type '{ b?: number; }'.
@@ -0,0 +1,11 @@
// forward ref ignored in a typeof
declare let s: typeof s1;
const s1 = "x";
// ignored anywhere in an interface (#35947)
interface Foo2 { [s2]: number; }
const s2 = "x";
// or in a type definition
type Foo3 = { [s3]: number; }
const s3 = "x";
@@ -0,0 +1,20 @@
// @strict: true
let obj: { a: { x: string } } & { c: number } = { a: { x: 'hello', y: 2 }, c: 5 }; // Nested excess property
declare let wrong: { a: { y: string } };
let weak: { a?: { x?: number } } & { c?: string } = wrong; // Nested weak object type
function foo<T extends object>(x: { a?: string }, y: T & { a: boolean }) {
x = y; // Mismatched property in source intersection
}
// Repro from #36637
interface Test {
readonly hi?: string[]
}
function test<T extends object>(value: T): Test {
return { ...value, hi: true }
}
@@ -0,0 +1,13 @@
namespace Foo {
export type Yep = { type: "foo.yep" };
}
namespace Bar {
export type Yep = { type: "bar.yep" };
}
const x = { type: "wat.nup" };
const val1: Foo.Yep | Bar.Yep = x;
const y = [{ type: "a" }, { type: "b" }];
const val2: [Foo.Yep, Bar.Yep] = y;
@@ -0,0 +1,14 @@
// @experimentalDecorators: true
// @emitDecoratorMetadata: true
// @target: es5
// @module: commonjs
declare var decorator: any;
class X {
@decorator()
a?: string?;
@decorator()
b?: string!;
@decorator()
c?: *;
}
@@ -0,0 +1,17 @@
// @checkJs: true
// @allowJs: true
// @declaration: true
// @emitDeclarationOnly: true
// @filename: instantiateTemplateTagTypeParameterOnVariableStatement.js
/**
* @template T
* @param {T} a
* @returns {(b: T) => T}
*/
const seq = a => b => b;
const text1 = "hello";
const text2 = "world";
/** @type {string} */
var text3 = seq(text1)(text2);
@@ -0,0 +1,28 @@
/// <reference path='fourslash.ts' />
////class Foo {
//// /**
//// * Property description
//// */
//// /*a*/_prop!: string; // comment/*b*/
////}
goTo.select("a", "b");
edit.applyRefactor({
refactorName: "Generate 'get' and 'set' accessors",
actionName: "Generate 'get' and 'set' accessors",
actionDescription: "Generate 'get' and 'set' accessors",
newContent:
`class Foo {
/**
* Property description
*/
private _prop!: string; // comment
public get /*RENAME*/prop(): string {
return this._prop;
}
public set prop(value: string) {
this._prop = value;
}
}`
});