Merge branch 'master' into reduceIntersectionTypes

This commit is contained in:
Anders Hejlsberg
2018-04-27 15:54:17 -07:00
84 changed files with 2664 additions and 1035 deletions
+4
View File
@@ -34,3 +34,7 @@
path = tests/cases/user/axios-src/axios-src
url = https://github.com/axios/axios.git
ignore = all
[submodule "tests/cases/user/prettier/prettier"]
path = tests/cases/user/prettier/prettier
url = https://github.com/prettier/prettier.git
ignore = all
+668 -890
View File
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -48,11 +48,12 @@
"@types/q": "latest",
"@types/run-sequence": "latest",
"@types/through2": "latest",
"@types/travis-fold": "latest",
"@types/xml2js": "^0.4.0",
"xml2js": "^0.4.19",
"browser-resolve": "^1.11.2",
"browserify": "latest",
"chai": "latest",
"chalk": "latest",
"convert-source-map": "latest",
"del": "latest",
"gulp": "3.X",
@@ -77,9 +78,9 @@
"through2": "latest",
"travis-fold": "latest",
"tslint": "latest",
"typescript": "next",
"vinyl": "latest",
"chalk": "latest",
"typescript": "next"
"xml2js": "^0.4.19"
},
"scripts": {
"pretest": "jake tests",
+1 -1
View File
@@ -178,7 +178,7 @@ function writeProtocolFile(outputFile: string, protocolTs: string, typeScriptSer
ts.sys.writeFile(outputFile, protocolDts);
if (diagnostics.length) {
const flattenedDiagnostics = diagnostics.map(d => `${ts.flattenDiagnosticMessageText(d.messageText, "\n")} at ${d.file.fileName} line ${d.start}`).join("\n");
const flattenedDiagnostics = diagnostics.map(d => `${ts.flattenDiagnosticMessageText(d.messageText, "\n")} at ${d.file ? d.file.fileName : "<unknown>"} line ${d.start}`).join("\n");
throw new Error(`Unexpected errors during sanity check: ${flattenedDiagnostics}`);
}
}
-1
View File
@@ -14,4 +14,3 @@ declare module "gulp-insert" {
}
declare module "sorcery";
declare module "travis-fold";
+130 -16
View File
@@ -2118,14 +2118,22 @@ namespace ts {
return (symbol.flags & meaning) || dontResolveAlias ? symbol : resolveAlias(symbol);
}
/**
* For prototype-property methods like `A.prototype.m = function () ...`, try to resolve names in the scope of `A` too.
* Note that prototype-property assignment to locations outside the current file (eg globals) doesn't work, so
* name resolution won't work either.
*/
function resolveEntityNameFromJSPrototype(name: Identifier, meaning: SymbolFlags) {
if (isJSDocTypeReference(name.parent) && isJSDocTag(name.parent.parent.parent)) {
const host = getJSDocHost(name.parent.parent.parent as JSDocTag);
if (isExpressionStatement(host) &&
isBinaryExpression(host.expression) &&
getSpecialPropertyAssignmentKind(host.expression) === SpecialPropertyAssignmentKind.PrototypeProperty) {
const secondaryLocation = getSymbolOfNode(host.expression.left).parent.valueDeclaration;
return resolveName(secondaryLocation, name.escapedText, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ true);
const symbol = getSymbolOfNode(host.expression.left);
if (symbol) {
const secondaryLocation = symbol.parent.valueDeclaration;
return resolveName(secondaryLocation, name.escapedText, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ true);
}
}
}
}
@@ -4156,7 +4164,7 @@ namespace ts {
const isPrivate = getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected);
const isSetOnlyAccessor = prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor);
if (!inNamesToRemove && !isPrivate && !isClassMethod(prop) && !isSetOnlyAccessor) {
members.set(prop.escapedName, prop);
members.set(prop.escapedName, getNonReadonlySymbol(prop));
}
}
const stringIndexInfo = getIndexInfoOfType(source, IndexKind.String);
@@ -4406,7 +4414,7 @@ namespace ts {
const special = getSpecialPropertyAssignmentKind(expression);
if (special === SpecialPropertyAssignmentKind.ThisProperty) {
const thisContainer = getThisContainer(expression, /*includeArrowFunctions*/ false);
// Properties defined in a constructor (or javascript constructor function) don't get undefined added.
// Properties defined in a constructor (or base constructor, or javascript constructor function) don't get undefined added.
// Function expressions that are assigned to the prototype count as methods.
declarationInConstructor = thisContainer.kind === SyntaxKind.Constructor ||
thisContainer.kind === SyntaxKind.FunctionDeclaration ||
@@ -4476,7 +4484,14 @@ namespace ts {
}
let type = jsDocType;
if (!type) {
// use only the constructor types unless only null | undefined (including widening variants) were assigned there
// use only the constructor types unless they were only assigned null | undefined (including widening variants)
if (definedInMethod) {
const propType = getTypeOfSpecialPropertyOfBaseType(symbol);
if (propType) {
(constructorTypes || (constructorTypes = [])).push(propType);
definedInConstructor = true;
}
}
const sourceTypes = some(constructorTypes, t => !!(t.flags & ~(TypeFlags.Nullable | TypeFlags.ContainsWideningType))) ? constructorTypes : types;
type = getUnionType(sourceTypes, UnionReduction.Subtype);
}
@@ -4490,6 +4505,20 @@ namespace ts {
return widened;
}
/** check for definition in base class if any declaration is in a class */
function getTypeOfSpecialPropertyOfBaseType(specialProperty: Symbol) {
const parentDeclaration = forEach(specialProperty.declarations, d => {
const parent = getThisContainer(d, /*includeArrowFunctions*/ false).parent;
return isClassLike(parent) && parent;
});
if (parentDeclaration) {
const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(parentDeclaration)) as InterfaceType;
const baseClassType = classType && getBaseTypes(classType)[0];
if (baseClassType) {
return getTypeOfPropertyOfType(baseClassType, specialProperty.escapedName);
}
}
}
// Return the type implied by a binding pattern element. This is the type of the initializer of the element if
// one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding
@@ -6425,6 +6454,47 @@ namespace ts {
return getConstraintOfDistributiveConditionalType(type) || getDefaultConstraintOfConditionalType(type);
}
function getUnionConstraintOfIntersection(type: IntersectionType, targetIsUnion: boolean) {
let constraints: Type[];
let hasDisjointDomainType = false;
for (const t of type.types) {
if (t.flags & TypeFlags.Instantiable) {
// We keep following constraints as long as we have an instantiable type that is known
// not to be circular or infinite (hence we stop on index access types).
let constraint = getConstraintOfType(t);
while (constraint && constraint.flags & (TypeFlags.TypeParameter | TypeFlags.Index | TypeFlags.Conditional)) {
constraint = getConstraintOfType(constraint);
}
if (constraint) {
// A constraint that isn't a union type implies that the final type would be a non-union
// type as well. Since non-union constraints are of no interest, we can exit here.
if (!(constraint.flags & TypeFlags.Union)) {
return undefined;
}
constraints = append(constraints, constraint);
}
}
else if (t.flags & TypeFlags.DisjointDomains) {
hasDisjointDomainType = true;
}
}
// If the target is a union type or if we are intersecting with types belonging to one of the
// disjoint domans, we may end up producing a constraint that hasn't been examined before.
if (constraints && (targetIsUnion || hasDisjointDomainType)) {
if (hasDisjointDomainType) {
// We add any types belong to one of the disjoint domans because they might cause the final
// intersection operation to reduce the union constraints.
for (const t of type.types) {
if (t.flags & TypeFlags.DisjointDomains) {
constraints = append(constraints, t);
}
}
}
return getIntersectionType(constraints);
}
return undefined;
}
function getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection(type: Type) {
if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection)) {
const constraint = getResolvedBaseConstraint(<InstantiableType | UnionOrIntersectionType>type);
@@ -6632,7 +6702,15 @@ namespace ts {
let nameType: Type;
const propTypes: Type[] = [];
let first = true;
let commonValueDeclaration: Declaration;
let hasNonUniformValueDeclaration = false;
for (const prop of props) {
if (!commonValueDeclaration) {
commonValueDeclaration = prop.valueDeclaration;
}
else if (prop.valueDeclaration !== commonValueDeclaration) {
hasNonUniformValueDeclaration = true;
}
declarations = addRange(declarations, prop.declarations);
const type = getTypeOfSymbol(prop);
if (first) {
@@ -6649,6 +6727,9 @@ namespace ts {
}
const result = createSymbol(SymbolFlags.Property | commonFlags, name, syntheticFlag | checkFlags);
result.containingType = containingType;
if (!hasNonUniformValueDeclaration && commonValueDeclaration) {
result.valueDeclaration = commonValueDeclaration;
}
result.declarations = declarations;
result.nameType = nameType;
result.type = isUnion ? getUnionType(propTypes) : getIntersectionType(propTypes);
@@ -7272,7 +7353,8 @@ namespace ts {
}
function getConstraintDeclaration(type: TypeParameter) {
return type.symbol && getDeclarationOfKind<TypeParameterDeclaration>(type.symbol, SyntaxKind.TypeParameter).constraint;
const decl = type.symbol && getDeclarationOfKind<TypeParameterDeclaration>(type.symbol, SyntaxKind.TypeParameter);
return decl && decl.constraint;
}
function getInferredTypeParameterConstraint(typeParameter: TypeParameter) {
@@ -7894,8 +7976,14 @@ namespace ts {
return binarySearch(types, type, getTypeId, compareValues) >= 0;
}
// Return true if the given intersection type contains (a) more than one unit type or (b) an object
// type and a nullable type (null or undefined).
// Return true if the given intersection type contains
// more than one unit type or,
// an object type and a nullable type (null or undefined), or
// a string-like type and a type known to be non-string-like, or
// a number-like type and a type known to be non-number-like, or
// a symbol-like type and a type known to be non-symbol-like, or
// a void-like type and a type known to be non-void-like, or
// a non-primitive type and a type known to be primitive.
function isEmptyIntersectionType(type: IntersectionType) {
let combined: TypeFlags = 0;
for (const t of type.types) {
@@ -7903,7 +7991,12 @@ namespace ts {
return true;
}
combined |= t.flags;
if (combined & TypeFlags.Nullable && combined & (TypeFlags.Object | TypeFlags.NonPrimitive)) {
if (combined & TypeFlags.Nullable && combined & (TypeFlags.Object | TypeFlags.NonPrimitive) ||
combined & TypeFlags.NonPrimitive && combined & (TypeFlags.DisjointDomains & ~TypeFlags.NonPrimitive) ||
combined & TypeFlags.StringLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.StringLike) ||
combined & TypeFlags.NumberLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.NumberLike) ||
combined & TypeFlags.ESSymbolLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.ESSymbolLike) ||
combined & TypeFlags.VoidLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.VoidLike)) {
return true;
}
}
@@ -10131,6 +10224,23 @@ namespace ts {
}
}
}
if (!result && source.flags & TypeFlags.Intersection) {
// The combined constraint of an intersection type is the intersection of the constraints of
// the constituents. When an intersection type contains instantiable types with union type
// constraints, there are situations where we need to examine the combined constraint. One is
// when the target is a union type. Another is when the intersection contains types belonging
// to one of the disjoint domains. For example, given type variables T and U, each with the
// constraint 'string | number', the combined constraint of 'T & U' is 'string | number' and
// we need to check this constraint against a union on the target side. Also, given a type
// variable V constrained to 'string | number', 'V & number' has a combined constraint of
// 'string & number | number & number' which reduces to just 'number'.
const constraint = getUnionConstraintOfIntersection(<IntersectionType>source, !!(target.flags & TypeFlags.Union));
if (constraint) {
if (result = isRelatedTo(constraint, target, reportErrors)) {
errorInfo = saveErrorInfo;
}
}
}
isIntersectionConstituent = saveIsIntersectionConstituent;
@@ -10488,11 +10598,14 @@ namespace ts {
}
}
// A type S is assignable to keyof T if S is assignable to keyof C, where C is the
// constraint of T.
const constraint = getConstraintForRelation((<IndexType>target).type);
if (constraint) {
if (result = isRelatedTo(source, getIndexType(constraint, (target as IndexType).stringsOnly), reportErrors)) {
return result;
// simplified form of T or, if T doesn't simplify, the constraint of T.
if (relation !== definitelyAssignableRelation) {
const simplified = getSimplifiedType((<IndexType>target).type);
const constraint = simplified !== (<IndexType>target).type ? simplified : getConstraintOfType((<IndexType>target).type);
if (constraint) {
if (result = isRelatedTo(source, getIndexType(constraint, (target as IndexType).stringsOnly), reportErrors)) {
return result;
}
}
}
}
@@ -10736,13 +10849,14 @@ namespace ts {
const sourcePropFlags = getDeclarationModifierFlagsFromSymbol(sourceProp);
const targetPropFlags = getDeclarationModifierFlagsFromSymbol(targetProp);
if (sourcePropFlags & ModifierFlags.Private || targetPropFlags & ModifierFlags.Private) {
if (getCheckFlags(sourceProp) & CheckFlags.ContainsPrivate) {
const hasDifferingDeclarations = sourceProp.valueDeclaration !== targetProp.valueDeclaration;
if (getCheckFlags(sourceProp) & CheckFlags.ContainsPrivate && hasDifferingDeclarations) {
if (reportErrors) {
reportError(Diagnostics.Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1, symbolToString(sourceProp), typeToString(source));
}
return Ternary.False;
}
if (sourceProp.valueDeclaration !== targetProp.valueDeclaration) {
if (hasDifferingDeclarations) {
if (reportErrors) {
if (sourcePropFlags & ModifierFlags.Private && targetPropFlags & ModifierFlags.Private) {
reportError(Diagnostics.Types_have_separate_declarations_of_a_private_property_0, symbolToString(targetProp));
+2 -2
View File
@@ -1441,9 +1441,9 @@ namespace ts {
function emitElementAccessExpression(node: ElementAccessExpression) {
emitExpression(node.expression);
const openPos = emitTokenWithComment(SyntaxKind.OpenBracketToken, node.expression.end, writePunctuation, node);
emitTokenWithComment(SyntaxKind.OpenBracketToken, node.expression.end, writePunctuation, node);
emitExpression(node.argumentExpression);
emitTokenWithComment(SyntaxKind.CloseBracketToken, node.argumentExpression ? node.argumentExpression.end : openPos, writePunctuation, node);
emitTokenWithComment(SyntaxKind.CloseBracketToken, node.argumentExpression.end, writePunctuation, node);
}
function emitCallExpression(node: CallExpression) {
+3
View File
@@ -3620,6 +3620,9 @@ namespace ts {
BooleanLike = Boolean | BooleanLiteral,
EnumLike = Enum | EnumLiteral,
ESSymbolLike = ESSymbol | UniqueESSymbol,
VoidLike = Void | Undefined,
/* @internal */
DisjointDomains = NonPrimitive | StringLike | NumberLike | BooleanLike | ESSymbolLike | VoidLike | Null,
UnionOrIntersection = Union | Intersection,
StructuredType = Object | Union | Intersection,
TypeVariable = TypeParameter | IndexedAccess,
+11 -3
View File
@@ -1889,7 +1889,13 @@ namespace ts {
export function getJSDocHost(node: JSDocTag): HasJSDoc {
while (node.parent.kind === SyntaxKind.JSDocTypeLiteral) {
node = node.parent.parent.parent as JSDocParameterTag;
if (node.parent.parent.kind === SyntaxKind.JSDocTypedefTag) {
node = node.parent.parent as JSDocTypedefTag;
}
else {
// node.parent.parent is a type expression, child of a parameter type
node = node.parent.parent.parent as JSDocParameterTag;
}
}
Debug.assert(node.parent!.kind === SyntaxKind.JSDocComment);
return node.parent!.parent!;
@@ -4025,12 +4031,14 @@ namespace ts {
}
/** Add a value to a set, and return true if it wasn't already present. */
export function addToSeen(seen: Map<true>, key: string | number): boolean {
export function addToSeen(seen: Map<true>, key: string | number): boolean;
export function addToSeen<T>(seen: Map<T>, key: string | number, value: T): boolean;
export function addToSeen<T>(seen: Map<T>, key: string | number, value: T = true as any): boolean {
key = String(key);
if (seen.has(key)) {
return false;
}
seen.set(key, true);
seen.set(key, value);
return true;
}
+2 -6
View File
@@ -304,14 +304,13 @@ namespace Utils {
o.containsParseError = true;
}
ts.forEach(Object.getOwnPropertyNames(n), propertyName => {
for (const propertyName of Object.getOwnPropertyNames(n) as ReadonlyArray<keyof ts.SourceFile | keyof ts.Identifier>) {
switch (propertyName) {
case "parent":
case "symbol":
case "locals":
case "localSymbol":
case "kind":
case "semanticDiagnostics":
case "id":
case "nodeCount":
case "symbolCount":
@@ -334,7 +333,6 @@ namespace Utils {
}
break;
case "referenceDiagnostics":
case "parseDiagnostics":
o[propertyName] = convertDiagnostics((<any>n)[propertyName]);
break;
@@ -355,9 +353,7 @@ namespace Utils {
default:
o[propertyName] = (<any>n)[propertyName];
}
return undefined;
});
}
return o;
}
@@ -1251,6 +1251,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_element_access_expression_should_take_an_argument_1011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An element access expression should take an argument.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Un'espressione di accesso a elementi deve accettare un argomento.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_enum_member_cannot_have_a_numeric_name_2452" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An enum member cannot have a numeric name.]]></Val>
@@ -6504,6 +6513,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Risolvere 'keyof' solo in nomi di proprietà con valori stringa (senza numeri o simboli).]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>
@@ -8754,6 +8772,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[La variabile '{0}' è dichiarata, ma non viene mai usata.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>
@@ -1241,6 +1241,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_element_access_expression_should_take_an_argument_1011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An element access expression should take an argument.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Wyrażenie dostępu do elementu powinno przyjmować argument.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_enum_member_cannot_have_a_numeric_name_2452" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An enum member cannot have a numeric name.]]></Val>
@@ -6494,6 +6503,9 @@
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Rozwiązuj elementy „keyof” tylko do nazw właściwości mających jako wartość ciągi (nie liczby czy symbole).]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -8747,6 +8759,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Element „{0}” jest zadeklarowany, ale nie jest nigdy używany.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>
@@ -1250,6 +1250,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_element_access_expression_should_take_an_argument_1011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An element access expression should take an argument.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Выражение доступа к элементу должно принимать аргумент.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_enum_member_cannot_have_a_numeric_name_2452" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An enum member cannot have a numeric name.]]></Val>
@@ -6506,6 +6515,9 @@
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Разрешать "keyof" только в имена свойств со строковым значением (не числа и не символы).]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -8759,6 +8771,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA["{0}" объявлен, но никогда не использовался.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>
@@ -899,6 +899,9 @@
<Item ItemId=";Add_0_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '{0}.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Çözümlenmemiş değişkene '{0}.' ekle]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -1001,6 +1004,9 @@
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Bir üye adıyla eşleşen tüm çözülmemiş değişkenlere niteleyici ekle]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -6491,6 +6497,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>
@@ -8741,6 +8753,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>
+8 -3
View File
@@ -98,16 +98,21 @@ namespace ts.codefix {
symbolToken: Node | undefined,
preferences: UserPreferences,
): { readonly moduleSpecifier: string, readonly codeAction: CodeAction } {
const exportInfos = getAllReExportingModules(exportedSymbol, symbolName, checker, allSourceFiles);
const exportInfos = getAllReExportingModules(exportedSymbol, moduleSymbol, symbolName, sourceFile, checker, allSourceFiles);
Debug.assert(exportInfos.some(info => info.moduleSymbol === moduleSymbol));
// We sort the best codefixes first, so taking `first` is best for completions.
const moduleSpecifier = first(getNewImportInfos(program, sourceFile, exportInfos, compilerOptions, getCanonicalFileName, host, preferences)).moduleSpecifier;
const ctx: ImportCodeFixContext = { host, program, checker, compilerOptions, sourceFile, formatContext, symbolName, getCanonicalFileName, symbolToken, preferences };
return { moduleSpecifier, codeAction: first(getCodeActionsForImport(exportInfos, ctx)) };
}
function getAllReExportingModules(exportedSymbol: Symbol, symbolName: string, checker: TypeChecker, allSourceFiles: ReadonlyArray<SourceFile>): ReadonlyArray<SymbolExportInfo> {
function getAllReExportingModules(exportedSymbol: Symbol, exportingModuleSymbol: Symbol, symbolName: string, sourceFile: SourceFile, checker: TypeChecker, allSourceFiles: ReadonlyArray<SourceFile>): ReadonlyArray<SymbolExportInfo> {
const result: SymbolExportInfo[] = [];
forEachExternalModule(checker, allSourceFiles, moduleSymbol => {
forEachExternalModule(checker, allSourceFiles, (moduleSymbol, moduleFile) => {
// Don't import from a re-export when looking "up" like to `./index` or `../index`.
if (moduleFile && moduleSymbol !== exportingModuleSymbol && startsWith(sourceFile.fileName, getDirectoryPath(moduleFile.fileName))) {
return;
}
for (const exported of checker.getExportsOfModule(moduleSymbol)) {
if (exported.escapedName === InternalSymbolName.Default || exported.name === symbolName && skipAlias(exported, checker) === exportedSymbol) {
const isDefaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol) === exported;
-1
View File
@@ -546,7 +546,6 @@ namespace ts {
public typeReferenceDirectives: FileReference[];
public syntacticDiagnostics: Diagnostic[];
public referenceDiagnostics: Diagnostic[];
public parseDiagnostics: Diagnostic[];
public bindDiagnostics: Diagnostic[];
+27 -24
View File
@@ -212,8 +212,7 @@ namespace ts.textChanges {
export class ChangeTracker {
private readonly changes: Change[] = [];
private readonly deletedNodesInLists: true[] = []; // Stores ids of nodes in lists that we already deleted. Used to avoid deleting `, ` twice in `a, b`.
// Map from class id to nodes to insert at the start
private readonly nodesInsertedAtClassStarts = createMap<{ sourceFile: SourceFile, cls: ClassLikeDeclaration, members: ClassElement[] }>();
private readonly classesWithNodesInsertedAtStart = createMap<ClassDeclaration>(); // Set<ClassDeclaration> implemented as Map<node id, ClassDeclaration>
public static fromContext(context: TextChangesContext): ChangeTracker {
return new ChangeTracker(getNewLineOrDefaultFromHost(context.host, context.formatContext.options), context.formatContext);
@@ -343,8 +342,7 @@ namespace ts.textChanges {
}
public insertNodeBefore(sourceFile: SourceFile, before: Node, newNode: Node, blankLineBetween = false) {
const pos = getAdjustedStartPosition(sourceFile, before, {}, Position.Start);
return this.replaceRange(sourceFile, { pos, end: pos }, newNode, this.getOptionsForInsertNodeBefore(before, blankLineBetween));
this.insertNodeAt(sourceFile, getAdjustedStartPosition(sourceFile, before, {}, Position.Start), newNode, this.getOptionsForInsertNodeBefore(before, blankLineBetween));
}
public insertModifierBefore(sourceFile: SourceFile, modifier: SyntaxKind, before: Node): void {
@@ -443,21 +441,20 @@ namespace ts.textChanges {
}
public insertNodeAtClassStart(sourceFile: SourceFile, cls: ClassLikeDeclaration, newElement: ClassElement): void {
const firstMember = firstOrUndefined(cls.members);
if (!firstMember) {
const id = getNodeId(cls).toString();
const newMembers = this.nodesInsertedAtClassStarts.get(id);
if (newMembers) {
Debug.assert(newMembers.sourceFile === sourceFile && newMembers.cls === cls);
newMembers.members.push(newElement);
}
else {
this.nodesInsertedAtClassStarts.set(id, { sourceFile, cls, members: [newElement] });
const clsStart = cls.getStart(sourceFile);
let prefix = "";
let suffix = this.newLineCharacter;
if (addToSeen(this.classesWithNodesInsertedAtStart, getNodeId(cls), cls)) {
prefix = this.newLineCharacter;
// For `class C {\n}`, don't add the trailing "\n"
if (cls.members.length === 0 && !(positionsAreOnSameLine as any)(...getClassBraceEnds(cls, sourceFile), sourceFile)) { // TODO: GH#4130 remove 'as any'
suffix = "";
}
}
else {
this.insertNodeBefore(sourceFile, firstMember, newElement);
}
const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options)
+ this.formatContext.options.indentSize;
this.insertNodeAt(sourceFile, cls.members.pos, newElement, { indentation, prefix, suffix });
}
public insertNodeAfter(sourceFile: SourceFile, after: Node, newNode: Node): this {
@@ -638,12 +635,14 @@ namespace ts.textChanges {
return this;
}
private finishInsertNodeAtClassStart(): void {
this.nodesInsertedAtClassStarts.forEach(({ sourceFile, cls, members }) => {
const newCls = cls.kind === SyntaxKind.ClassDeclaration
? updateClassDeclaration(cls, cls.decorators, cls.modifiers, cls.name, cls.typeParameters, cls.heritageClauses, members)
: updateClassExpression(cls, cls.modifiers, cls.name, cls.typeParameters, cls.heritageClauses, members);
this.replaceNode(sourceFile, cls, newCls);
private finishClassesWithNodesInsertedAtStart(): void {
this.classesWithNodesInsertedAtStart.forEach(cls => {
const sourceFile = cls.getSourceFile();
const [openBraceEnd, closeBraceEnd] = getClassBraceEnds(cls, sourceFile);
// For `class C { }` remove the whitespace inside the braces.
if (positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile) && openBraceEnd !== closeBraceEnd - 1) {
this.deleteRange(sourceFile, createTextRange(openBraceEnd, closeBraceEnd - 1));
}
});
}
@@ -654,11 +653,15 @@ namespace ts.textChanges {
* so we can only call this once and can't get the non-formatted text separately.
*/
public getChanges(validate?: ValidateNonFormattedText): FileTextChanges[] {
this.finishInsertNodeAtClassStart();
this.finishClassesWithNodesInsertedAtStart();
return changesToText.getTextChangesFromChanges(this.changes, this.newLineCharacter, this.formatContext, validate);
}
}
function getClassBraceEnds(cls: ClassLikeDeclaration, sourceFile: SourceFile): [number, number] {
return [findChildOfKind(cls, SyntaxKind.OpenBraceToken, sourceFile).end, findChildOfKind(cls, SyntaxKind.CloseBraceToken, sourceFile).end];
}
export type ValidateNonFormattedText = (node: Node, text: string) => void;
namespace changesToText {
+1 -1
View File
@@ -331,7 +331,7 @@ namespace ts {
applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
/** @deprecated `fileName` will be ignored */
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[];
getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[];
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined): RefactorEditInfo | undefined;
organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): ReadonlyArray<FileTextChanges>;
getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings): ReadonlyArray<FileTextChanges>;
+2 -1
View File
@@ -2111,6 +2111,7 @@ declare namespace ts {
BooleanLike = 136,
EnumLike = 272,
ESSymbolLike = 1536,
VoidLike = 6144,
UnionOrIntersection = 393216,
StructuredType = 458752,
TypeVariable = 1081344,
@@ -4451,7 +4452,7 @@ declare namespace ts {
applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
/** @deprecated `fileName` will be ignored */
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[];
getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[];
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined): RefactorEditInfo | undefined;
organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): ReadonlyArray<FileTextChanges>;
getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings): ReadonlyArray<FileTextChanges>;
+2 -1
View File
@@ -2111,6 +2111,7 @@ declare namespace ts {
BooleanLike = 136,
EnumLike = 272,
ESSymbolLike = 1536,
VoidLike = 6144,
UnionOrIntersection = 393216,
StructuredType = 458752,
TypeVariable = 1081344,
@@ -4451,7 +4452,7 @@ declare namespace ts {
applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
/** @deprecated `fileName` will be ignored */
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[];
getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[];
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined): RefactorEditInfo | undefined;
organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): ReadonlyArray<FileTextChanges>;
getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings): ReadonlyArray<FileTextChanges>;
@@ -0,0 +1,42 @@
//// [doubleMixinConditionalTypeBaseClassWorks.ts]
type Constructor = new (...args: any[]) => {};
const Mixin1 = <C extends Constructor>(Base: C) => class extends Base { private _fooPrivate: {}; }
type FooConstructor = typeof Mixin1 extends (a: Constructor) => infer Cls ? Cls : never;
const Mixin2 = <C extends FooConstructor>(Base: C) => class extends Base {};
class C extends Mixin2(Mixin1(Object)) {}
//// [doubleMixinConditionalTypeBaseClassWorks.js]
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var Mixin1 = function (Base) { return /** @class */ (function (_super) {
__extends(class_1, _super);
function class_1() {
return _super !== null && _super.apply(this, arguments) || this;
}
return class_1;
}(Base)); };
var Mixin2 = function (Base) { return /** @class */ (function (_super) {
__extends(class_2, _super);
function class_2() {
return _super !== null && _super.apply(this, arguments) || this;
}
return class_2;
}(Base)); };
var C = /** @class */ (function (_super) {
__extends(C, _super);
function C() {
return _super !== null && _super.apply(this, arguments) || this;
}
return C;
}(Mixin2(Mixin1(Object))));
@@ -0,0 +1,36 @@
=== tests/cases/compiler/doubleMixinConditionalTypeBaseClassWorks.ts ===
type Constructor = new (...args: any[]) => {};
>Constructor : Symbol(Constructor, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 0, 0))
>args : Symbol(args, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 0, 24))
const Mixin1 = <C extends Constructor>(Base: C) => class extends Base { private _fooPrivate: {}; }
>Mixin1 : Symbol(Mixin1, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 5))
>C : Symbol(C, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 16))
>Constructor : Symbol(Constructor, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 0, 0))
>Base : Symbol(Base, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 39))
>C : Symbol(C, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 16))
>Base : Symbol(Base, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 39))
>_fooPrivate : Symbol((Anonymous class)._fooPrivate, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 71))
type FooConstructor = typeof Mixin1 extends (a: Constructor) => infer Cls ? Cls : never;
>FooConstructor : Symbol(FooConstructor, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 98))
>Mixin1 : Symbol(Mixin1, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 5))
>a : Symbol(a, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 4, 45))
>Constructor : Symbol(Constructor, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 0, 0))
>Cls : Symbol(Cls, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 4, 69))
>Cls : Symbol(Cls, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 4, 69))
const Mixin2 = <C extends FooConstructor>(Base: C) => class extends Base {};
>Mixin2 : Symbol(Mixin2, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 5, 5))
>C : Symbol(C, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 5, 16))
>FooConstructor : Symbol(FooConstructor, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 98))
>Base : Symbol(Base, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 5, 42))
>C : Symbol(C, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 5, 16))
>Base : Symbol(Base, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 5, 42))
class C extends Mixin2(Mixin1(Object)) {}
>C : Symbol(C, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 5, 76))
>Mixin2 : Symbol(Mixin2, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 5, 5))
>Mixin1 : Symbol(Mixin1, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 5))
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
@@ -0,0 +1,42 @@
=== tests/cases/compiler/doubleMixinConditionalTypeBaseClassWorks.ts ===
type Constructor = new (...args: any[]) => {};
>Constructor : Constructor
>args : any[]
const Mixin1 = <C extends Constructor>(Base: C) => class extends Base { private _fooPrivate: {}; }
>Mixin1 : <C extends Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
><C extends Constructor>(Base: C) => class extends Base { private _fooPrivate: {}; } : <C extends Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
>C : C
>Constructor : Constructor
>Base : C
>C : C
>class extends Base { private _fooPrivate: {}; } : { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
>Base : {}
>_fooPrivate : {}
type FooConstructor = typeof Mixin1 extends (a: Constructor) => infer Cls ? Cls : never;
>FooConstructor : { new (...args: any[]): <Constructor>.(Anonymous class); prototype: <any>.(Anonymous class); } & Constructor
>Mixin1 : <C extends Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
>a : Constructor
>Constructor : Constructor
>Cls : Cls
>Cls : Cls
const Mixin2 = <C extends FooConstructor>(Base: C) => class extends Base {};
>Mixin2 : <C extends { new (...args: any[]): <Constructor>.(Anonymous class); prototype: <any>.(Anonymous class); } & Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
><C extends FooConstructor>(Base: C) => class extends Base {} : <C extends { new (...args: any[]): <Constructor>.(Anonymous class); prototype: <any>.(Anonymous class); } & Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
>C : C
>FooConstructor : { new (...args: any[]): <Constructor>.(Anonymous class); prototype: <any>.(Anonymous class); } & Constructor
>Base : C
>C : C
>class extends Base {} : { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
>Base : <Constructor>.(Anonymous class)
class C extends Mixin2(Mixin1(Object)) {}
>C : C
>Mixin2(Mixin1(Object)) : <{ new (...args: any[]): <ObjectConstructor>.(Anonymous class); prototype: <any>.(Anonymous class); } & ObjectConstructor>.(Anonymous class) & <ObjectConstructor>.(Anonymous class) & Object
>Mixin2 : <C extends { new (...args: any[]): <Constructor>.(Anonymous class); prototype: <any>.(Anonymous class); } & Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
>Mixin1(Object) : { new (...args: any[]): <ObjectConstructor>.(Anonymous class); prototype: <any>.(Anonymous class); } & ObjectConstructor
>Mixin1 : <C extends Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & C
>Object : ObjectConstructor
@@ -1,11 +1,9 @@
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(17,5): error TS2322: Type 'A & B' is not assignable to type 'number'.
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(18,5): error TS2322: Type 'A & B' is not assignable to type 'boolean'.
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(19,5): error TS2322: Type 'A & B' is not assignable to type 'string'.
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(21,5): error TS2322: Type '(number & true) | (number & false)' is not assignable to type 'string'.
Type 'number & true' is not assignable to type 'string'.
==== tests/cases/compiler/errorMessagesIntersectionTypes04.ts (4 errors) ====
==== tests/cases/compiler/errorMessagesIntersectionTypes04.ts (3 errors) ====
interface A {
a;
}
@@ -33,7 +31,4 @@ tests/cases/compiler/errorMessagesIntersectionTypes04.ts(21,5): error TS2322: Ty
!!! error TS2322: Type 'A & B' is not assignable to type 'string'.
str = num_and_bool;
~~~
!!! error TS2322: Type '(number & true) | (number & false)' is not assignable to type 'string'.
!!! error TS2322: Type 'number & true' is not assignable to type 'string'.
}
@@ -36,7 +36,7 @@ function f<T, U extends A, V extends U>(): void {
>B : B
let num_and_bool: number & boolean;
>num_and_bool : (number & true) | (number & false)
>num_and_bool : never
num = a_and_b;
>num = a_and_b : A & B
@@ -54,7 +54,7 @@ function f<T, U extends A, V extends U>(): void {
>a_and_b : A & B
str = num_and_bool;
>str = num_and_bool : (number & true) | (number & false)
>str = num_and_bool : never
>str : string
>num_and_bool : (number & true) | (number & false)
>num_and_bool : never
}
@@ -0,0 +1,25 @@
=== tests/cases/conformance/salsa/a.js ===
class Base {
>Base : Symbol(Base, Decl(a.js, 0, 0))
constructor() {
this.p = 1
>this.p : Symbol(Base.p, Decl(a.js, 1, 19))
>this : Symbol(Base, Decl(a.js, 0, 0))
>p : Symbol(Base.p, Decl(a.js, 1, 19))
}
}
class Derived extends Base {
>Derived : Symbol(Derived, Decl(a.js, 4, 1))
>Base : Symbol(Base, Decl(a.js, 0, 0))
m() {
>m : Symbol(Derived.m, Decl(a.js, 5, 28))
this.p = 1
>this.p : Symbol(Derived.p, Decl(a.js, 6, 9))
>this : Symbol(Derived, Decl(a.js, 4, 1))
>p : Symbol(Derived.p, Decl(a.js, 6, 9))
}
}
@@ -0,0 +1,29 @@
=== tests/cases/conformance/salsa/a.js ===
class Base {
>Base : Base
constructor() {
this.p = 1
>this.p = 1 : 1
>this.p : number
>this : this
>p : number
>1 : 1
}
}
class Derived extends Base {
>Derived : Derived
>Base : Base
m() {
>m : () => void
this.p = 1
>this.p = 1 : 1
>this.p : number
>this : this
>p : number
>1 : 1
}
}
@@ -0,0 +1,28 @@
=== tests/cases/conformance/salsa/a.js ===
class Base {
>Base : Symbol(Base, Decl(a.js, 0, 0))
m() {
>m : Symbol(Base.m, Decl(a.js, 0, 12))
this.p = 1
>this.p : Symbol(Base.p, Decl(a.js, 1, 9))
>this : Symbol(Base, Decl(a.js, 0, 0))
>p : Symbol(Base.p, Decl(a.js, 1, 9))
}
}
class Derived extends Base {
>Derived : Symbol(Derived, Decl(a.js, 4, 1))
>Base : Symbol(Base, Decl(a.js, 0, 0))
m() {
>m : Symbol(Derived.m, Decl(a.js, 5, 28))
// should be OK, and p should have type number | undefined from its base
this.p = 1
>this.p : Symbol(Derived.p, Decl(a.js, 6, 9))
>this : Symbol(Derived, Decl(a.js, 4, 1))
>p : Symbol(Derived.p, Decl(a.js, 6, 9))
}
}
@@ -0,0 +1,32 @@
=== tests/cases/conformance/salsa/a.js ===
class Base {
>Base : Base
m() {
>m : () => void
this.p = 1
>this.p = 1 : 1
>this.p : number | undefined
>this : this
>p : number | undefined
>1 : 1
}
}
class Derived extends Base {
>Derived : Derived
>Base : Base
m() {
>m : () => void
// should be OK, and p should have type number | undefined from its base
this.p = 1
>this.p = 1 : 1
>this.p : number | undefined
>this : this
>p : number | undefined
>1 : 1
}
}
@@ -0,0 +1,37 @@
=== tests/cases/conformance/salsa/a.js ===
class Base {
>Base : Symbol(Base, Decl(a.js, 0, 0))
m() {
>m : Symbol(Base.m, Decl(a.js, 0, 12))
this.p = 1
>this.p : Symbol(Base.p, Decl(a.js, 1, 9))
>this : Symbol(Base, Decl(a.js, 0, 0))
>p : Symbol(Base.p, Decl(a.js, 1, 9))
}
}
class Derived extends Base {
>Derived : Symbol(Derived, Decl(a.js, 4, 1))
>Base : Symbol(Base, Decl(a.js, 0, 0))
constructor() {
super();
>super : Symbol(Base, Decl(a.js, 0, 0))
// should be OK, and p should have type number from this assignment
this.p = 1
>this.p : Symbol(Derived.p, Decl(a.js, 7, 16))
>this : Symbol(Derived, Decl(a.js, 4, 1))
>p : Symbol(Derived.p, Decl(a.js, 7, 16))
}
test() {
>test : Symbol(Derived.test, Decl(a.js, 10, 5))
return this.p
>this.p : Symbol(Derived.p, Decl(a.js, 7, 16))
>this : Symbol(Derived, Decl(a.js, 4, 1))
>p : Symbol(Derived.p, Decl(a.js, 7, 16))
}
}
@@ -0,0 +1,42 @@
=== tests/cases/conformance/salsa/a.js ===
class Base {
>Base : Base
m() {
>m : () => void
this.p = 1
>this.p = 1 : 1
>this.p : number | undefined
>this : this
>p : number | undefined
>1 : 1
}
}
class Derived extends Base {
>Derived : Derived
>Base : Base
constructor() {
super();
>super() : void
>super : typeof Base
// should be OK, and p should have type number from this assignment
this.p = 1
>this.p = 1 : 1
>this.p : number
>this : this
>p : number
>1 : 1
}
test() {
>test : () => number
return this.p
>this.p : number
>this : this
>p : number
}
}
@@ -0,0 +1,83 @@
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(7,9): error TS2322: Type 'T & U' is not assignable to type 'string | number'.
Type 'string | undefined' is not assignable to type 'string | number'.
Type 'undefined' is not assignable to type 'string | number'.
Type 'T & U' is not assignable to type 'number'.
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(8,9): error TS2322: Type 'T & U' is not assignable to type 'string | null'.
Type 'string | undefined' is not assignable to type 'string | null'.
Type 'undefined' is not assignable to type 'string | null'.
Type 'T & U' is not assignable to type 'string'.
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(10,9): error TS2322: Type 'T & U' is not assignable to type 'number | null'.
Type 'string | undefined' is not assignable to type 'number | null'.
Type 'undefined' is not assignable to type 'number | null'.
Type 'T & U' is not assignable to type 'number'.
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(11,9): error TS2322: Type 'T & U' is not assignable to type 'number | undefined'.
Type 'string | undefined' is not assignable to type 'number | undefined'.
Type 'string' is not assignable to type 'number | undefined'.
Type 'T & U' is not assignable to type 'number'.
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(12,9): error TS2322: Type 'T & U' is not assignable to type 'null | undefined'.
Type 'string | undefined' is not assignable to type 'null | undefined'.
Type 'string' is not assignable to type 'null | undefined'.
Type 'T & U' is not assignable to type 'null'.
==== tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts (5 errors) ====
function f1<T extends string | number, U extends string | number>(x: T & U) {
// Combined constraint of 'T & U' is 'string | number'
let y: string | number = x;
}
function f2<T extends string | number | undefined, U extends string | null | undefined>(x: T & U) {
let y1: string | number = x; // Error
~~
!!! error TS2322: Type 'T & U' is not assignable to type 'string | number'.
!!! error TS2322: Type 'string | undefined' is not assignable to type 'string | number'.
!!! error TS2322: Type 'undefined' is not assignable to type 'string | number'.
!!! error TS2322: Type 'T & U' is not assignable to type 'number'.
let y2: string | null = x; // Error
~~
!!! error TS2322: Type 'T & U' is not assignable to type 'string | null'.
!!! error TS2322: Type 'string | undefined' is not assignable to type 'string | null'.
!!! error TS2322: Type 'undefined' is not assignable to type 'string | null'.
!!! error TS2322: Type 'T & U' is not assignable to type 'string'.
let y3: string | undefined = x;
let y4: number | null = x; // Error
~~
!!! error TS2322: Type 'T & U' is not assignable to type 'number | null'.
!!! error TS2322: Type 'string | undefined' is not assignable to type 'number | null'.
!!! error TS2322: Type 'undefined' is not assignable to type 'number | null'.
!!! error TS2322: Type 'T & U' is not assignable to type 'number'.
let y5: number | undefined = x; // Error
~~
!!! error TS2322: Type 'T & U' is not assignable to type 'number | undefined'.
!!! error TS2322: Type 'string | undefined' is not assignable to type 'number | undefined'.
!!! error TS2322: Type 'string' is not assignable to type 'number | undefined'.
!!! error TS2322: Type 'T & U' is not assignable to type 'number'.
let y6: null | undefined = x; // Error
~~
!!! error TS2322: Type 'T & U' is not assignable to type 'null | undefined'.
!!! error TS2322: Type 'string | undefined' is not assignable to type 'null | undefined'.
!!! error TS2322: Type 'string' is not assignable to type 'null | undefined'.
!!! error TS2322: Type 'T & U' is not assignable to type 'null'.
}
type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined
function f3<T extends string | number | undefined>(x: T & (number | object | undefined)) {
const y: number | undefined = x;
}
function f4<T extends string | number>(x: T & (number | object)) {
const y: number = x;
}
function f5<T, U extends keyof T>(x: keyof T & U) {
let y: keyof any = x;
}
// Repro from #23648
type Example<T, U> = { [K in keyof T]: K extends keyof U ? UnexpectedError<K> : NoErrorHere<K> }
type UnexpectedError<T extends PropertyKey> = T
type NoErrorHere<T extends PropertyKey> = T
@@ -0,0 +1,60 @@
//// [intersectionWithUnionConstraint.ts]
function f1<T extends string | number, U extends string | number>(x: T & U) {
// Combined constraint of 'T & U' is 'string | number'
let y: string | number = x;
}
function f2<T extends string | number | undefined, U extends string | null | undefined>(x: T & U) {
let y1: string | number = x; // Error
let y2: string | null = x; // Error
let y3: string | undefined = x;
let y4: number | null = x; // Error
let y5: number | undefined = x; // Error
let y6: null | undefined = x; // Error
}
type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined
function f3<T extends string | number | undefined>(x: T & (number | object | undefined)) {
const y: number | undefined = x;
}
function f4<T extends string | number>(x: T & (number | object)) {
const y: number = x;
}
function f5<T, U extends keyof T>(x: keyof T & U) {
let y: keyof any = x;
}
// Repro from #23648
type Example<T, U> = { [K in keyof T]: K extends keyof U ? UnexpectedError<K> : NoErrorHere<K> }
type UnexpectedError<T extends PropertyKey> = T
type NoErrorHere<T extends PropertyKey> = T
//// [intersectionWithUnionConstraint.js]
"use strict";
function f1(x) {
// Combined constraint of 'T & U' is 'string | number'
var y = x;
}
function f2(x) {
var y1 = x; // Error
var y2 = x; // Error
var y3 = x;
var y4 = x; // Error
var y5 = x; // Error
var y6 = x; // Error
}
function f3(x) {
var y = x;
}
function f4(x) {
var y = x;
}
function f5(x) {
var y = x;
}
@@ -0,0 +1,114 @@
=== tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts ===
function f1<T extends string | number, U extends string | number>(x: T & U) {
>f1 : Symbol(f1, Decl(intersectionWithUnionConstraint.ts, 0, 0))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 0, 12))
>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 0, 38))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 0, 66))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 0, 12))
>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 0, 38))
// Combined constraint of 'T & U' is 'string | number'
let y: string | number = x;
>y : Symbol(y, Decl(intersectionWithUnionConstraint.ts, 2, 7))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 0, 66))
}
function f2<T extends string | number | undefined, U extends string | null | undefined>(x: T & U) {
>f2 : Symbol(f2, Decl(intersectionWithUnionConstraint.ts, 3, 1))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 5, 12))
>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 5, 50))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 5, 12))
>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 5, 50))
let y1: string | number = x; // Error
>y1 : Symbol(y1, Decl(intersectionWithUnionConstraint.ts, 6, 7))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88))
let y2: string | null = x; // Error
>y2 : Symbol(y2, Decl(intersectionWithUnionConstraint.ts, 7, 7))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88))
let y3: string | undefined = x;
>y3 : Symbol(y3, Decl(intersectionWithUnionConstraint.ts, 8, 7))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88))
let y4: number | null = x; // Error
>y4 : Symbol(y4, Decl(intersectionWithUnionConstraint.ts, 9, 7))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88))
let y5: number | undefined = x; // Error
>y5 : Symbol(y5, Decl(intersectionWithUnionConstraint.ts, 10, 7))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88))
let y6: null | undefined = x; // Error
>y6 : Symbol(y6, Decl(intersectionWithUnionConstraint.ts, 11, 7))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88))
}
type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined
>T1 : Symbol(T1, Decl(intersectionWithUnionConstraint.ts, 12, 1))
function f3<T extends string | number | undefined>(x: T & (number | object | undefined)) {
>f3 : Symbol(f3, Decl(intersectionWithUnionConstraint.ts, 14, 70))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 16, 12))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 16, 51))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 16, 12))
const y: number | undefined = x;
>y : Symbol(y, Decl(intersectionWithUnionConstraint.ts, 17, 9))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 16, 51))
}
function f4<T extends string | number>(x: T & (number | object)) {
>f4 : Symbol(f4, Decl(intersectionWithUnionConstraint.ts, 18, 1))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 20, 12))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 20, 39))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 20, 12))
const y: number = x;
>y : Symbol(y, Decl(intersectionWithUnionConstraint.ts, 21, 9))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 20, 39))
}
function f5<T, U extends keyof T>(x: keyof T & U) {
>f5 : Symbol(f5, Decl(intersectionWithUnionConstraint.ts, 22, 1))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 24, 12))
>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 24, 14))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 24, 12))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 24, 34))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 24, 12))
>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 24, 14))
let y: keyof any = x;
>y : Symbol(y, Decl(intersectionWithUnionConstraint.ts, 25, 7))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 24, 34))
}
// Repro from #23648
type Example<T, U> = { [K in keyof T]: K extends keyof U ? UnexpectedError<K> : NoErrorHere<K> }
>Example : Symbol(Example, Decl(intersectionWithUnionConstraint.ts, 26, 1))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 30, 13))
>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 30, 15))
>K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 30, 24))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 30, 13))
>K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 30, 24))
>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 30, 15))
>UnexpectedError : Symbol(UnexpectedError, Decl(intersectionWithUnionConstraint.ts, 30, 96))
>K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 30, 24))
>NoErrorHere : Symbol(NoErrorHere, Decl(intersectionWithUnionConstraint.ts, 32, 47))
>K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 30, 24))
type UnexpectedError<T extends PropertyKey> = T
>UnexpectedError : Symbol(UnexpectedError, Decl(intersectionWithUnionConstraint.ts, 30, 96))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 32, 21))
>PropertyKey : Symbol(PropertyKey, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 32, 21))
type NoErrorHere<T extends PropertyKey> = T
>NoErrorHere : Symbol(NoErrorHere, Decl(intersectionWithUnionConstraint.ts, 32, 47))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 33, 17))
>PropertyKey : Symbol(PropertyKey, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 33, 17))
@@ -0,0 +1,119 @@
=== tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts ===
function f1<T extends string | number, U extends string | number>(x: T & U) {
>f1 : <T extends string | number, U extends string | number>(x: T & U) => void
>T : T
>U : U
>x : T & U
>T : T
>U : U
// Combined constraint of 'T & U' is 'string | number'
let y: string | number = x;
>y : string | number
>x : T & U
}
function f2<T extends string | number | undefined, U extends string | null | undefined>(x: T & U) {
>f2 : <T extends string | number | undefined, U extends string | null | undefined>(x: T & U) => void
>T : T
>U : U
>null : null
>x : T & U
>T : T
>U : U
let y1: string | number = x; // Error
>y1 : string | number
>x : T & U
let y2: string | null = x; // Error
>y2 : string | null
>null : null
>x : T & U
let y3: string | undefined = x;
>y3 : string | undefined
>x : T & U
let y4: number | null = x; // Error
>y4 : number | null
>null : null
>x : T & U
let y5: number | undefined = x; // Error
>y5 : number | undefined
>x : T & U
let y6: null | undefined = x; // Error
>y6 : null | undefined
>null : null
>x : T & U
}
type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined
>T1 : string | undefined
>null : null
function f3<T extends string | number | undefined>(x: T & (number | object | undefined)) {
>f3 : <T extends string | number | undefined>(x: (T & undefined) | (T & number) | (T & object)) => void
>T : T
>x : (T & undefined) | (T & number) | (T & object)
>T : T
const y: number | undefined = x;
>y : number | undefined
>x : (T & undefined) | (T & number) | (T & object)
}
function f4<T extends string | number>(x: T & (number | object)) {
>f4 : <T extends string | number>(x: (T & number) | (T & object)) => void
>T : T
>x : (T & number) | (T & object)
>T : T
const y: number = x;
>y : number
>x : (T & number) | (T & object)
}
function f5<T, U extends keyof T>(x: keyof T & U) {
>f5 : <T, U extends keyof T>(x: keyof T & U) => void
>T : T
>U : U
>T : T
>x : keyof T & U
>T : T
>U : U
let y: keyof any = x;
>y : string | number | symbol
>x : keyof T & U
}
// Repro from #23648
type Example<T, U> = { [K in keyof T]: K extends keyof U ? UnexpectedError<K> : NoErrorHere<K> }
>Example : Example<T, U>
>T : T
>U : U
>K : K
>T : T
>K : K
>U : U
>UnexpectedError : T
>K : K
>NoErrorHere : T
>K : K
type UnexpectedError<T extends PropertyKey> = T
>UnexpectedError : T
>T : T
>PropertyKey : string | number | symbol
>T : T
type NoErrorHere<T extends PropertyKey> = T
>NoErrorHere : T
>T : T
>PropertyKey : string | number | symbol
>T : T
@@ -1,7 +1,8 @@
tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js(21,1): error TS2322: Type 'false' is not assignable to type 'number'.
tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js(26,15): error TS2304: Cannot find name 'T'.
==== tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js (1 errors) ====
==== tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js (2 errors) ====
/**
* @template {T}
* @param {T} t
@@ -25,4 +26,14 @@ tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js(21,1): error T
z.u = false
~~~
!!! error TS2322: Type 'false' is not assignable to type 'number'.
// lookup in typedef should not crash the compiler, even when the type is unknown
/**
* @typedef {Object} A
* @property {T} value
~
!!! error TS2304: Cannot find name 'T'.
*/
/** @type {A} */
const options = { value: null };
@@ -54,3 +54,13 @@ z.u = false
>z : Symbol(z, Decl(templateTagWithNestedTypeLiteral.js, 18, 3))
>u : Symbol(Zet.u, Decl(templateTagWithNestedTypeLiteral.js, 4, 17), Decl(templateTagWithNestedTypeLiteral.js, 14, 36))
// lookup in typedef should not crash the compiler, even when the type is unknown
/**
* @typedef {Object} A
* @property {T} value
*/
/** @type {A} */
const options = { value: null };
>options : Symbol(options, Decl(templateTagWithNestedTypeLiteral.js, 28, 5))
>value : Symbol(value, Decl(templateTagWithNestedTypeLiteral.js, 28, 17))
@@ -72,3 +72,15 @@ z.u = false
>u : number
>false : false
// lookup in typedef should not crash the compiler, even when the type is unknown
/**
* @typedef {Object} A
* @property {T} value
*/
/** @type {A} */
const options = { value: null };
>options : { value: any; }
>{ value: null } : { value: null; }
>value : null
>null : null
@@ -0,0 +1,30 @@
tests/cases/conformance/jsdoc/forgot.js(23,19): error TS2339: Property 'animate' does not exist on type 'Element'.
==== tests/cases/conformance/jsdoc/forgot.js (1 errors) ====
/**
* @param {T} a
* @template T
*/
function f(a) {
return () => a
}
let n = f(1)()
/**
* @param {T} a
* @template T
* @returns {function(): T}
*/
function g(a) {
return () => a
}
let s = g('hi')()
/**
* @param {Array.<Object>} keyframes - Can't look up types on Element since it's a global in another file. (But it shouldn't crash).
*/
Element.prototype.animate = function(keyframes) {};
~~~~~~~
!!! error TS2339: Property 'animate' does not exist on type 'Element'.
@@ -30,3 +30,12 @@ let s = g('hi')()
>s : Symbol(s, Decl(forgot.js, 17, 3))
>g : Symbol(g, Decl(forgot.js, 7, 14))
/**
* @param {Array.<Object>} keyframes - Can't look up types on Element since it's a global in another file. (But it shouldn't crash).
*/
Element.prototype.animate = function(keyframes) {};
>Element.prototype : Symbol(prototype, Decl(lib.dom.d.ts, --, --))
>Element : Symbol(Element, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
>prototype : Symbol(prototype, Decl(lib.dom.d.ts, --, --))
>keyframes : Symbol(keyframes, Decl(forgot.js, 22, 37))
@@ -38,3 +38,16 @@ let s = g('hi')()
>g : <T>(a: T) => () => T
>'hi' : "hi"
/**
* @param {Array.<Object>} keyframes - Can't look up types on Element since it's a global in another file. (But it shouldn't crash).
*/
Element.prototype.animate = function(keyframes) {};
>Element.prototype.animate = function(keyframes) {} : (keyframes: any[]) => void
>Element.prototype.animate : any
>Element.prototype : Element
>Element : { new (): Element; prototype: Element; }
>prototype : Element
>animate : any
>function(keyframes) {} : (keyframes: any[]) => void
>keyframes : any[]
@@ -566,6 +566,15 @@ type Predicates<TaggedRecord> = {
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]
}
// Repros from #23592
type Example<T extends { [K in keyof T]: { prop: any } }> = { [K in keyof T]: T[K]["prop"] };
type Result = Example<{ a: { prop: string }; b: { prop: number } }>;
type Helper2<T> = { [K in keyof T]: Extract<T[K], { prop: any }> };
type Example2<T> = { [K in keyof Helper2<T>]: Helper2<T>[K]["prop"] };
type Result2 = Example2<{ 1: { prop: string }; 2: { prop: number } }>;
// Repro from #23618
type DBBoolTable<K extends string> = { [k in K]: 0 | 1 }
@@ -1241,6 +1250,37 @@ declare function f3<T, K extends Extract<keyof T, string>>(t: T, k: K, tk: T[K])
declare type Predicates<TaggedRecord> = {
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T];
};
declare type Example<T extends {
[K in keyof T]: {
prop: any;
};
}> = {
[K in keyof T]: T[K]["prop"];
};
declare type Result = Example<{
a: {
prop: string;
};
b: {
prop: number;
};
}>;
declare type Helper2<T> = {
[K in keyof T]: Extract<T[K], {
prop: any;
}>;
};
declare type Example2<T> = {
[K in keyof Helper2<T>]: Helper2<T>[K]["prop"];
};
declare type Result2 = Example2<{
1: {
prop: string;
};
2: {
prop: number;
};
}>;
declare type DBBoolTable<K extends string> = {
[k in K]: 0 | 1;
};
@@ -2010,64 +2010,113 @@ type Predicates<TaggedRecord> = {
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 564, 3))
}
// Repros from #23592
type Example<T extends { [K in keyof T]: { prop: any } }> = { [K in keyof T]: T[K]["prop"] };
>Example : Symbol(Example, Decl(keyofAndIndexedAccess.ts, 565, 1))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 569, 13))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 26))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 569, 13))
>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 569, 42))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 63))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 569, 13))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 569, 13))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 63))
type Result = Example<{ a: { prop: string }; b: { prop: number } }>;
>Result : Symbol(Result, Decl(keyofAndIndexedAccess.ts, 569, 93))
>Example : Symbol(Example, Decl(keyofAndIndexedAccess.ts, 565, 1))
>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 570, 23))
>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 570, 28))
>b : Symbol(b, Decl(keyofAndIndexedAccess.ts, 570, 44))
>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 570, 49))
type Helper2<T> = { [K in keyof T]: Extract<T[K], { prop: any }> };
>Helper2 : Symbol(Helper2, Decl(keyofAndIndexedAccess.ts, 570, 68))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 572, 13))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 572, 21))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 572, 13))
>Extract : Symbol(Extract, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 572, 13))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 572, 21))
>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 572, 51))
type Example2<T> = { [K in keyof Helper2<T>]: Helper2<T>[K]["prop"] };
>Example2 : Symbol(Example2, Decl(keyofAndIndexedAccess.ts, 572, 67))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 573, 14))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 573, 22))
>Helper2 : Symbol(Helper2, Decl(keyofAndIndexedAccess.ts, 570, 68))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 573, 14))
>Helper2 : Symbol(Helper2, Decl(keyofAndIndexedAccess.ts, 570, 68))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 573, 14))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 573, 22))
type Result2 = Example2<{ 1: { prop: string }; 2: { prop: number } }>;
>Result2 : Symbol(Result2, Decl(keyofAndIndexedAccess.ts, 573, 70))
>Example2 : Symbol(Example2, Decl(keyofAndIndexedAccess.ts, 572, 67))
>1 : Symbol(1, Decl(keyofAndIndexedAccess.ts, 574, 25))
>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 574, 30))
>2 : Symbol(2, Decl(keyofAndIndexedAccess.ts, 574, 46))
>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 574, 51))
// Repro from #23618
type DBBoolTable<K extends string> = { [k in K]: 0 | 1 }
>DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 565, 1))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 17))
>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 569, 40))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 17))
>DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 574, 70))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 578, 17))
>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 578, 40))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 578, 17))
enum Flag {
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 569, 56))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 578, 56))
FLAG_1 = "flag_1",
>FLAG_1 : Symbol(Flag.FLAG_1, Decl(keyofAndIndexedAccess.ts, 570, 11))
>FLAG_1 : Symbol(Flag.FLAG_1, Decl(keyofAndIndexedAccess.ts, 579, 11))
FLAG_2 = "flag_2"
>FLAG_2 : Symbol(Flag.FLAG_2, Decl(keyofAndIndexedAccess.ts, 571, 22))
>FLAG_2 : Symbol(Flag.FLAG_2, Decl(keyofAndIndexedAccess.ts, 580, 22))
}
type SimpleDBRecord<Flag extends string> = { staticField: number } & DBBoolTable<Flag>
>SimpleDBRecord : Symbol(SimpleDBRecord, Decl(keyofAndIndexedAccess.ts, 573, 1))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 575, 20))
>staticField : Symbol(staticField, Decl(keyofAndIndexedAccess.ts, 575, 44))
>DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 565, 1))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 575, 20))
>SimpleDBRecord : Symbol(SimpleDBRecord, Decl(keyofAndIndexedAccess.ts, 582, 1))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 584, 20))
>staticField : Symbol(staticField, Decl(keyofAndIndexedAccess.ts, 584, 44))
>DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 574, 70))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 584, 20))
function getFlagsFromSimpleRecord<Flag extends string>(record: SimpleDBRecord<Flag>, flags: Flag[]) {
>getFlagsFromSimpleRecord : Symbol(getFlagsFromSimpleRecord, Decl(keyofAndIndexedAccess.ts, 575, 86))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 576, 34))
>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 576, 55))
>SimpleDBRecord : Symbol(SimpleDBRecord, Decl(keyofAndIndexedAccess.ts, 573, 1))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 576, 34))
>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 576, 84))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 576, 34))
>getFlagsFromSimpleRecord : Symbol(getFlagsFromSimpleRecord, Decl(keyofAndIndexedAccess.ts, 584, 86))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 585, 34))
>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 585, 55))
>SimpleDBRecord : Symbol(SimpleDBRecord, Decl(keyofAndIndexedAccess.ts, 582, 1))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 585, 34))
>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 585, 84))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 585, 34))
return record[flags[0]];
>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 576, 55))
>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 576, 84))
>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 585, 55))
>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 585, 84))
}
type DynamicDBRecord<Flag extends string> = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable<Flag>
>DynamicDBRecord : Symbol(DynamicDBRecord, Decl(keyofAndIndexedAccess.ts, 578, 1))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 580, 21))
>dynamicField : Symbol(dynamicField, Decl(keyofAndIndexedAccess.ts, 580, 46))
>dynamicField : Symbol(dynamicField, Decl(keyofAndIndexedAccess.ts, 580, 73))
>DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 565, 1))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 580, 21))
>DynamicDBRecord : Symbol(DynamicDBRecord, Decl(keyofAndIndexedAccess.ts, 587, 1))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 589, 21))
>dynamicField : Symbol(dynamicField, Decl(keyofAndIndexedAccess.ts, 589, 46))
>dynamicField : Symbol(dynamicField, Decl(keyofAndIndexedAccess.ts, 589, 73))
>DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 574, 70))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 589, 21))
function getFlagsFromDynamicRecord<Flag extends string>(record: DynamicDBRecord<Flag>, flags: Flag[]) {
>getFlagsFromDynamicRecord : Symbol(getFlagsFromDynamicRecord, Decl(keyofAndIndexedAccess.ts, 580, 117))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 581, 35))
>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 581, 56))
>DynamicDBRecord : Symbol(DynamicDBRecord, Decl(keyofAndIndexedAccess.ts, 578, 1))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 581, 35))
>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 581, 86))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 581, 35))
>getFlagsFromDynamicRecord : Symbol(getFlagsFromDynamicRecord, Decl(keyofAndIndexedAccess.ts, 589, 117))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 590, 35))
>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 590, 56))
>DynamicDBRecord : Symbol(DynamicDBRecord, Decl(keyofAndIndexedAccess.ts, 587, 1))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 590, 35))
>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 590, 86))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 590, 35))
return record[flags[0]];
>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 581, 56))
>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 581, 86))
>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 590, 56))
>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 590, 86))
}
@@ -2345,6 +2345,55 @@ type Predicates<TaggedRecord> = {
>T : T
}
// Repros from #23592
type Example<T extends { [K in keyof T]: { prop: any } }> = { [K in keyof T]: T[K]["prop"] };
>Example : Example<T>
>T : T
>K : K
>T : T
>prop : any
>K : K
>T : T
>T : T
>K : K
type Result = Example<{ a: { prop: string }; b: { prop: number } }>;
>Result : Example<{ a: { prop: string; }; b: { prop: number; }; }>
>Example : Example<T>
>a : { prop: string; }
>prop : string
>b : { prop: number; }
>prop : number
type Helper2<T> = { [K in keyof T]: Extract<T[K], { prop: any }> };
>Helper2 : Helper2<T>
>T : T
>K : K
>T : T
>Extract : Extract<T, U>
>T : T
>K : K
>prop : any
type Example2<T> = { [K in keyof Helper2<T>]: Helper2<T>[K]["prop"] };
>Example2 : Example2<T>
>T : T
>K : K
>Helper2 : Helper2<T>
>T : T
>Helper2 : Helper2<T>
>T : T
>K : K
type Result2 = Example2<{ 1: { prop: string }; 2: { prop: number } }>;
>Result2 : Example2<{ 1: { prop: string; }; 2: { prop: number; }; }>
>Example2 : Example2<T>
>1 : { prop: string; }
>prop : string
>2 : { prop: number; }
>prop : number
// Repro from #23618
type DBBoolTable<K extends string> = { [k in K]: 0 | 1 }
@@ -44,6 +44,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(87,5): error
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(103,9): error TS2322: Type 'Extract<keyof T, string>' is not assignable to type 'K'.
Type 'string & keyof T' is not assignable to type 'K'.
Type 'string' is not assignable to type 'K'.
Type 'string' is not assignable to type 'K'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(105,9): error TS2322: Type 'T[Extract<keyof T, string>]' is not assignable to type 'T[K]'.
Type 'Extract<keyof T, string>' is not assignable to type 'K'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(108,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'.
@@ -55,6 +56,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(114,5): error
Type 'Extract<keyof T, string>' is not assignable to type 'J'.
Type 'string & keyof T' is not assignable to type 'J'.
Type 'string' is not assignable to type 'J'.
Type 'string' is not assignable to type 'J'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(117,5): error TS2322: Type 'T[K]' is not assignable to type 'U[J]'.
Type 'T' is not assignable to type 'U'.
@@ -238,6 +240,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(117,5): error
!!! error TS2322: Type 'Extract<keyof T, string>' is not assignable to type 'K'.
!!! error TS2322: Type 'string & keyof T' is not assignable to type 'K'.
!!! error TS2322: Type 'string' is not assignable to type 'K'.
!!! error TS2322: Type 'string' is not assignable to type 'K'.
t[key] = tk; // ok, T[K] ==> T[keyof T]
tk = t[key]; // error, T[keyof T] =/=> T[K]
~~
@@ -264,6 +267,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(117,5): error
!!! error TS2322: Type 'Extract<keyof T, string>' is not assignable to type 'J'.
!!! error TS2322: Type 'string & keyof T' is not assignable to type 'J'.
!!! error TS2322: Type 'string' is not assignable to type 'J'.
!!! error TS2322: Type 'string' is not assignable to type 'J'.
tk = uj;
uj = tk; // error
@@ -34,19 +34,19 @@ type T02 = keyof keyof Object;
>Object : Object
type T03 = keyof keyof keyof Object;
>T03 : "toString" | "valueOf" | ("toString" & number) | ("toLocaleString" & number) | ("valueOf" & number) | ("toFixed" & number) | ("toExponential" & number) | ("toPrecision" & number)
>T03 : "toString" | "valueOf"
>Object : Object
type T04 = keyof keyof keyof keyof Object;
>T04 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | ("toString" & number) | ("valueOf" & number) | (number & "length") | (number & "toString") | (number & "toLocaleString") | (number & "valueOf") | (number & "charAt") | (number & "charCodeAt") | (number & "concat") | (number & "indexOf") | (number & "lastIndexOf") | (number & "localeCompare") | (number & "match") | (number & "replace") | (number & "search") | (number & "slice") | (number & "split") | (number & "substring") | (number & "toLowerCase") | (number & "toLocaleLowerCase") | (number & "toUpperCase") | (number & "toLocaleUpperCase") | (number & "trim") | (number & "substr") | (number & "toFixed") | (number & "toExponential") | (number & "toPrecision") | ("length" & number) | ("charAt" & number) | ("charCodeAt" & number) | ("concat" & number) | ("indexOf" & number) | ("lastIndexOf" & number) | ("localeCompare" & number) | ("match" & number) | ("replace" & number) | ("search" & number) | ("slice" & number) | ("split" & number) | ("substring" & number) | ("toLowerCase" & number) | ("toLocaleLowerCase" & number) | ("toUpperCase" & number) | ("toLocaleUpperCase" & number) | ("trim" & number) | ("substr" & number)
>T04 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr"
>Object : Object
type T05 = keyof keyof keyof keyof keyof Object;
>T05 : "toString" | "valueOf" | ("toString" & number) | ("toLocaleString" & number) | ("valueOf" & number) | ("toFixed" & number) | ("toExponential" & number) | ("toPrecision" & number)
>T05 : "toString" | "valueOf"
>Object : Object
type T06 = keyof keyof keyof keyof keyof keyof Object;
>T06 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | ("toString" & number) | ("valueOf" & number) | (number & "length") | (number & "toString") | (number & "toLocaleString") | (number & "valueOf") | (number & "charAt") | (number & "charCodeAt") | (number & "concat") | (number & "indexOf") | (number & "lastIndexOf") | (number & "localeCompare") | (number & "match") | (number & "replace") | (number & "search") | (number & "slice") | (number & "split") | (number & "substring") | (number & "toLowerCase") | (number & "toLocaleLowerCase") | (number & "toUpperCase") | (number & "toLocaleUpperCase") | (number & "trim") | (number & "substr") | (number & "toFixed") | (number & "toExponential") | (number & "toPrecision") | ("length" & number) | ("charAt" & number) | ("charCodeAt" & number) | ("concat" & number) | ("indexOf" & number) | ("lastIndexOf" & number) | ("localeCompare" & number) | ("match" & number) | ("replace" & number) | ("search" & number) | ("slice" & number) | ("split" & number) | ("substring" & number) | ("toLowerCase" & number) | ("toLocaleLowerCase" & number) | ("toUpperCase" & number) | ("toLocaleUpperCase" & number) | ("trim" & number) | ("substr" & number)
>T06 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr"
>Object : Object
type T10 = Shape["name"];
@@ -0,0 +1,48 @@
//// [noCrashOnThisTypeUsage.ts]
interface IListenable {
changeListeners: Function[] | null
observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean): void
}
function notifyListeners<T>(listenable: IListenable, change: T) {
}
export class ObservableValue<T> {
constructor(
public value: T
) {
const newValue: T = value;
const oldValue: any = null;
notifyListeners(this, {
type: "update",
object: this,
newValue,
oldValue
});
}
changeListeners: Function[] | null = [];
observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean) {}
}
//// [noCrashOnThisTypeUsage.js]
"use strict";
exports.__esModule = true;
function notifyListeners(listenable, change) {
}
var ObservableValue = /** @class */ (function () {
function ObservableValue(value) {
this.value = value;
this.changeListeners = [];
var newValue = value;
var oldValue = null;
notifyListeners(this, {
type: "update",
object: this,
newValue: newValue,
oldValue: oldValue
});
}
ObservableValue.prototype.observe = function (handler, fireImmediately) { };
return ObservableValue;
}());
exports.ObservableValue = ObservableValue;
@@ -0,0 +1,73 @@
=== tests/cases/compiler/noCrashOnThisTypeUsage.ts ===
interface IListenable {
>IListenable : Symbol(IListenable, Decl(noCrashOnThisTypeUsage.ts, 0, 0))
changeListeners: Function[] | null
>changeListeners : Symbol(IListenable.changeListeners, Decl(noCrashOnThisTypeUsage.ts, 0, 23))
>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean): void
>observe : Symbol(IListenable.observe, Decl(noCrashOnThisTypeUsage.ts, 1, 38))
>handler : Symbol(handler, Decl(noCrashOnThisTypeUsage.ts, 2, 12))
>change : Symbol(change, Decl(noCrashOnThisTypeUsage.ts, 2, 22))
>oldValue : Symbol(oldValue, Decl(noCrashOnThisTypeUsage.ts, 2, 34))
>fireImmediately : Symbol(fireImmediately, Decl(noCrashOnThisTypeUsage.ts, 2, 59))
}
function notifyListeners<T>(listenable: IListenable, change: T) {
>notifyListeners : Symbol(notifyListeners, Decl(noCrashOnThisTypeUsage.ts, 3, 1))
>T : Symbol(T, Decl(noCrashOnThisTypeUsage.ts, 5, 25))
>listenable : Symbol(listenable, Decl(noCrashOnThisTypeUsage.ts, 5, 28))
>IListenable : Symbol(IListenable, Decl(noCrashOnThisTypeUsage.ts, 0, 0))
>change : Symbol(change, Decl(noCrashOnThisTypeUsage.ts, 5, 52))
>T : Symbol(T, Decl(noCrashOnThisTypeUsage.ts, 5, 25))
}
export class ObservableValue<T> {
>ObservableValue : Symbol(ObservableValue, Decl(noCrashOnThisTypeUsage.ts, 6, 1))
>T : Symbol(T, Decl(noCrashOnThisTypeUsage.ts, 8, 29))
constructor(
public value: T
>value : Symbol(ObservableValue.value, Decl(noCrashOnThisTypeUsage.ts, 9, 16))
>T : Symbol(T, Decl(noCrashOnThisTypeUsage.ts, 8, 29))
) {
const newValue: T = value;
>newValue : Symbol(newValue, Decl(noCrashOnThisTypeUsage.ts, 12, 13))
>T : Symbol(T, Decl(noCrashOnThisTypeUsage.ts, 8, 29))
>value : Symbol(value, Decl(noCrashOnThisTypeUsage.ts, 9, 16))
const oldValue: any = null;
>oldValue : Symbol(oldValue, Decl(noCrashOnThisTypeUsage.ts, 13, 13))
notifyListeners(this, {
>notifyListeners : Symbol(notifyListeners, Decl(noCrashOnThisTypeUsage.ts, 3, 1))
>this : Symbol(ObservableValue, Decl(noCrashOnThisTypeUsage.ts, 6, 1))
type: "update",
>type : Symbol(type, Decl(noCrashOnThisTypeUsage.ts, 14, 31))
object: this,
>object : Symbol(object, Decl(noCrashOnThisTypeUsage.ts, 15, 27))
>this : Symbol(ObservableValue, Decl(noCrashOnThisTypeUsage.ts, 6, 1))
newValue,
>newValue : Symbol(newValue, Decl(noCrashOnThisTypeUsage.ts, 16, 25))
oldValue
>oldValue : Symbol(oldValue, Decl(noCrashOnThisTypeUsage.ts, 17, 21))
});
}
changeListeners: Function[] | null = [];
>changeListeners : Symbol(ObservableValue.changeListeners, Decl(noCrashOnThisTypeUsage.ts, 20, 5))
>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean) {}
>observe : Symbol(ObservableValue.observe, Decl(noCrashOnThisTypeUsage.ts, 21, 44))
>handler : Symbol(handler, Decl(noCrashOnThisTypeUsage.ts, 22, 12))
>change : Symbol(change, Decl(noCrashOnThisTypeUsage.ts, 22, 22))
>oldValue : Symbol(oldValue, Decl(noCrashOnThisTypeUsage.ts, 22, 34))
>fireImmediately : Symbol(fireImmediately, Decl(noCrashOnThisTypeUsage.ts, 22, 59))
}
@@ -0,0 +1,80 @@
=== tests/cases/compiler/noCrashOnThisTypeUsage.ts ===
interface IListenable {
>IListenable : IListenable
changeListeners: Function[] | null
>changeListeners : Function[] | null
>Function : Function
>null : null
observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean): void
>observe : (handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean | undefined) => void
>handler : (change: any, oldValue?: any) => void
>change : any
>oldValue : any
>fireImmediately : boolean | undefined
}
function notifyListeners<T>(listenable: IListenable, change: T) {
>notifyListeners : <T>(listenable: IListenable, change: T) => void
>T : T
>listenable : IListenable
>IListenable : IListenable
>change : T
>T : T
}
export class ObservableValue<T> {
>ObservableValue : ObservableValue<T>
>T : T
constructor(
public value: T
>value : T
>T : T
) {
const newValue: T = value;
>newValue : T
>T : T
>value : T
const oldValue: any = null;
>oldValue : any
>null : null
notifyListeners(this, {
>notifyListeners(this, { type: "update", object: this, newValue, oldValue }) : void
>notifyListeners : <T>(listenable: IListenable, change: T) => void
>this : this
>{ type: "update", object: this, newValue, oldValue } : { type: string; object: this; newValue: T; oldValue: any; }
type: "update",
>type : string
>"update" : "update"
object: this,
>object : this
>this : this
newValue,
>newValue : T
oldValue
>oldValue : any
});
}
changeListeners: Function[] | null = [];
>changeListeners : Function[] | null
>Function : Function
>null : null
>[] : never[]
observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean) {}
>observe : (handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean | undefined) => void
>handler : (change: any, oldValue?: any) => void
>change : any
>oldValue : any
>fireImmediately : boolean | undefined
}
@@ -0,0 +1,36 @@
//// [objectRestReadonly.ts]
// #23734
type ObjType = {
foo: string
baz: string
quux: string
}
const obj: Readonly<ObjType> = {
foo: 'bar',
baz: 'qux',
quux: 'quuz',
}
const { foo, ...rest } = obj
delete rest.baz
//// [objectRestReadonly.js]
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
};
var obj = {
foo: 'bar',
baz: 'qux',
quux: 'quuz'
};
var foo = obj.foo, rest = __rest(obj, ["foo"]);
delete rest.baz;
@@ -0,0 +1,40 @@
=== tests/cases/conformance/types/rest/objectRestReadonly.ts ===
// #23734
type ObjType = {
>ObjType : Symbol(ObjType, Decl(objectRestReadonly.ts, 0, 0))
foo: string
>foo : Symbol(foo, Decl(objectRestReadonly.ts, 1, 16))
baz: string
>baz : Symbol(baz, Decl(objectRestReadonly.ts, 2, 13))
quux: string
>quux : Symbol(quux, Decl(objectRestReadonly.ts, 3, 13))
}
const obj: Readonly<ObjType> = {
>obj : Symbol(obj, Decl(objectRestReadonly.ts, 7, 5))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>ObjType : Symbol(ObjType, Decl(objectRestReadonly.ts, 0, 0))
foo: 'bar',
>foo : Symbol(foo, Decl(objectRestReadonly.ts, 7, 32))
baz: 'qux',
>baz : Symbol(baz, Decl(objectRestReadonly.ts, 8, 13))
quux: 'quuz',
>quux : Symbol(quux, Decl(objectRestReadonly.ts, 9, 13))
}
const { foo, ...rest } = obj
>foo : Symbol(foo, Decl(objectRestReadonly.ts, 13, 7))
>rest : Symbol(rest, Decl(objectRestReadonly.ts, 13, 12))
>obj : Symbol(obj, Decl(objectRestReadonly.ts, 7, 5))
delete rest.baz
>rest.baz : Symbol(baz, Decl(objectRestReadonly.ts, 2, 13))
>rest : Symbol(rest, Decl(objectRestReadonly.ts, 13, 12))
>baz : Symbol(baz, Decl(objectRestReadonly.ts, 2, 13))
@@ -0,0 +1,45 @@
=== tests/cases/conformance/types/rest/objectRestReadonly.ts ===
// #23734
type ObjType = {
>ObjType : ObjType
foo: string
>foo : string
baz: string
>baz : string
quux: string
>quux : string
}
const obj: Readonly<ObjType> = {
>obj : Readonly<ObjType>
>Readonly : Readonly<T>
>ObjType : ObjType
>{ foo: 'bar', baz: 'qux', quux: 'quuz',} : { foo: string; baz: string; quux: string; }
foo: 'bar',
>foo : string
>'bar' : "bar"
baz: 'qux',
>baz : string
>'qux' : "qux"
quux: 'quuz',
>quux : string
>'quuz' : "quuz"
}
const { foo, ...rest } = obj
>foo : string
>rest : { baz: string; quux: string; }
>obj : Readonly<ObjType>
delete rest.baz
>delete rest.baz : boolean
>rest.baz : string
>rest : { baz: string; quux: string; }
>baz : string
@@ -1,10 +1,7 @@
tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts(18,10): error TS2678: Type '(number & true) | (number & false)' is not comparable to type 'string & number'.
Type 'number & false' is not comparable to type 'string & number'.
Type 'number & false' is not comparable to type 'string'.
tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts(22,10): error TS2678: Type 'boolean' is not comparable to type 'string & number'.
==== tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts (2 errors) ====
==== tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts (1 errors) ====
var strAndNum: string & number;
var numAndBool: number & boolean;
var str: string;
@@ -23,10 +20,6 @@ tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithInterse
// Overlap in constituents
case numAndBool:
~~~~~~~~~~
!!! error TS2678: Type '(number & true) | (number & false)' is not comparable to type 'string & number'.
!!! error TS2678: Type 'number & false' is not comparable to type 'string & number'.
!!! error TS2678: Type 'number & false' is not comparable to type 'string'.
break;
// No relation
@@ -3,7 +3,7 @@ var strAndNum: string & number;
>strAndNum : string & number
var numAndBool: number & boolean;
>numAndBool : (number & true) | (number & false)
>numAndBool : never
var str: string;
>str : string
@@ -34,7 +34,7 @@ switch (strAndNum) {
// Overlap in constituents
case numAndBool:
>numAndBool : (number & true) | (number & false)
>numAndBool : never
break;
@@ -25,7 +25,7 @@ if (!(result instanceof RegExp)) {
} else if (!result.global) {
>!result.global : boolean
>result.global : (string & true) | (string & false)
>result.global : never
>result : I & RegExp
>global : (string & true) | (string & false)
>global : never
}
@@ -0,0 +1,92 @@
Exit Code: 1
Standard output:
index.js(3,25): error TS2307: Cannot find module './package.json'.
index.js(138,21): error TS2532: Object is possibly 'undefined'.
src/cli/util.js(262,64): error TS2339: Property 'length' does not exist on type 'Ignore'.
src/cli/util.js(335,52): error TS2339: Property 'length' does not exist on type 'Ignore'.
src/cli/util.js(396,46): error TS2345: Argument of type 'null' is not assignable to parameter of type 'number | undefined'.
src/cli/util.js(403,39): error TS2339: Property 'grey' does not exist on type 'typeof import("/home/nathansa/ts/node_modules/chalk/types/index")'.
src/common/parser-create-error.js(8,9): error TS2339: Property 'loc' does not exist on type 'SyntaxError'.
src/config/resolve-config.js(75,32): error TS2345: Argument of type '{ sync: false; }' is not assignable to parameter of type '{ cache: boolean; sync: boolean; }'.
Property 'cache' is missing in type '{ sync: false; }'.
src/config/resolve-config.js(82,32): error TS2345: Argument of type '{ sync: true; }' is not assignable to parameter of type '{ cache: boolean; sync: boolean; }'.
Property 'cache' is missing in type '{ sync: true; }'.
src/doc/doc-printer.js(213,17): error TS2532: Object is possibly 'undefined'.
src/doc/doc-printer.js(214,18): error TS2532: Object is possibly 'undefined'.
src/doc/doc-printer.js(215,17): error TS2532: Object is possibly 'undefined'.
src/language-css/clean.js(3,30): error TS2307: Cannot find module 'html-tag-names'.
src/language-css/parser-postcss.js(78,32): error TS2345: Argument of type '{ [x: string]: any; groups: never[]; type: string; }' is not assignable to parameter of type 'never'.
src/language-css/parser-postcss.js(88,30): error TS2345: Argument of type '{ [x: string]: any; open: null; close: null; groups: never[]; type: string; }' is not assignable to parameter of type 'never'.
src/language-css/parser-postcss.js(93,30): error TS2345: Argument of type '{ [x: string]: any; groups: never[]; type: string; }' is not assignable to parameter of type 'never'.
src/language-css/parser-postcss.js(100,30): error TS2345: Argument of type 'any' is not assignable to parameter of type 'never'.
src/language-css/parser-postcss.js(104,28): error TS2345: Argument of type '{ [x: string]: any; groups: never[]; type: string; }' is not assignable to parameter of type 'never'.
src/language-css/parser-postcss.js(407,32): error TS2531: Object is possibly 'null'.
src/language-css/printer-postcss.js(3,30): error TS2307: Cannot find module 'html-tag-names'.
src/language-handlebars/parser-glimmer.js(27,26): error TS2345: Argument of type '{ plugins: { ast: (() => { [x: string]: any; visitor: { [x: string]: any; Program(node: any): voi...' is not assignable to parameter of type 'PreprocessOptions | undefined'.
Type '{ plugins: { ast: (() => { [x: string]: any; visitor: { [x: string]: any; Program(node: any): voi...' is not assignable to type 'PreprocessOptions'.
Types of property 'plugins' are incompatible.
Type '{ ast: (() => { [x: string]: any; visitor: { [x: string]: any; Program(node: any): void; ElementN...' is not assignable to type '{ ast?: ASTPluginBuilder[] | undefined; } | undefined'.
Type '{ ast: (() => { [x: string]: any; visitor: { [x: string]: any; Program(node: any): void; ElementN...' is not assignable to type '{ ast?: ASTPluginBuilder[] | undefined; }'.
Types of property 'ast' are incompatible.
Type '(() => { [x: string]: any; visitor: { [x: string]: any; Program(node: any): void; ElementNode(nod...' is not assignable to type 'ASTPluginBuilder[] | undefined'.
Type '(() => { [x: string]: any; visitor: { [x: string]: any; Program(node: any): void; ElementNode(nod...' is not assignable to type 'ASTPluginBuilder[]'.
Type '() => { [x: string]: any; visitor: { [x: string]: any; Program(node: any): void; ElementNode(node...' is not assignable to type 'ASTPluginBuilder'.
Type '{ [x: string]: any; visitor: { [x: string]: any; Program(node: any): void; ElementNode(node: any)...' is not assignable to type 'ASTPlugin'.
Property 'name' is missing in type '{ [x: string]: any; visitor: { [x: string]: any; Program(node: any): void; ElementNode(node: any)...'.
src/language-handlebars/printer-glimmer.js(270,7): error TS2554: Expected 0-1 arguments, but got 2.
src/language-js/printer-estree.js(99,9): error TS2322: Type '{ [x: string]: any; type: string; }' is not assignable to type '{ [x: string]: any; type: string; parts: any; }'.
Property 'parts' is missing in type '{ [x: string]: any; type: string; }'.
src/language-js/printer-estree.js(302,9): error TS2345: Argument of type '{ [x: string]: any; type: string; parts: any; } | { [x: string]: any; type: string; contents: any...' is not assignable to parameter of type 'ConcatArray<never>'.
Type '{ [x: string]: any; type: string; parts: any; }' is not assignable to type 'ConcatArray<never>'.
Property 'length' is missing in type '{ [x: string]: any; type: string; parts: any; }'.
src/language-js/printer-estree.js(1224,28): error TS2345: Argument of type '{ [x: string]: any; type: string; parts: any; }' is not assignable to parameter of type 'string | ConcatArray<string>'.
Type '{ [x: string]: any; type: string; parts: any; }' is not assignable to type 'ConcatArray<string>'.
Property 'length' is missing in type '{ [x: string]: any; type: string; parts: any; }'.
src/language-js/printer-estree.js(1601,20): error TS2345: Argument of type '" "' is not assignable to parameter of type '{ [x: string]: any; type: string; contents: any; break: boolean; expandedStates: any; }'.
src/language-js/printer-estree.js(1603,20): error TS2345: Argument of type '{ [x: string]: any; type: string; parts: any; }' is not assignable to parameter of type '{ [x: string]: any; type: string; contents: any; break: boolean; expandedStates: any; }'.
Property 'contents' is missing in type '{ [x: string]: any; type: string; parts: any; }'.
src/language-js/printer-estree.js(1605,18): error TS2345: Argument of type '"while ("' is not assignable to parameter of type '{ [x: string]: any; type: string; contents: any; break: boolean; expandedStates: any; }'.
src/language-js/printer-estree.js(1614,9): error TS2345: Argument of type '")"' is not assignable to parameter of type '{ [x: string]: any; type: string; contents: any; break: boolean; expandedStates: any; }'.
src/language-js/printer-estree.js(3293,23): error TS2532: Object is possibly 'undefined'.
src/language-js/printer-estree.js(3294,24): error TS2532: Object is possibly 'undefined'.
src/language-js/printer-estree.js(3647,5): error TS2345: Argument of type '"" | { [x: string]: any; type: string; parts: any; } | { [x: string]: any; type: string; contents...' is not assignable to parameter of type 'string'.
Type '{ [x: string]: any; type: string; parts: any; }' is not assignable to type 'string'.
src/language-js/printer-estree.js(3651,16): error TS2345: Argument of type '{ [x: string]: any; type: string; parts: any; }' is not assignable to parameter of type 'string'.
src/language-js/printer-estree.js(3693,9): error TS2345: Argument of type '{ [x: string]: any; type: string; parts: any; }' is not assignable to parameter of type 'string'.
src/language-js/printer-estree.js(3995,14): error TS2554: Expected 0-2 arguments, but got 3.
src/language-js/printer-estree.js(5034,9): error TS2554: Expected 0-1 arguments, but got 2.
src/language-js/printer-estree.js(5070,7): error TS2345: Argument of type '(string | number)[]' is not assignable to parameter of type '((childPath: any) => any) | ConcatArray<(childPath: any) => any>'.
Type '(string | number)[]' is not assignable to type 'ConcatArray<(childPath: any) => any>'.
Types of property 'slice' are incompatible.
Type '(start?: number | undefined, end?: number | undefined) => (string | number)[]' is not assignable to type '(start?: number | undefined, end?: number | undefined) => ((childPath: any) => any)[]'.
Type '(string | number)[]' is not assignable to type '((childPath: any) => any)[]'.
Type 'string | number' is not assignable to type '(childPath: any) => any'.
Type 'string' is not assignable to type '(childPath: any) => any'.
src/language-markdown/printer-markdown.js(258,18): error TS2532: Object is possibly 'undefined'.
src/language-markdown/printer-markdown.js(259,17): error TS2532: Object is possibly 'undefined'.
src/language-markdown/printer-markdown.js(283,14): error TS2532: Object is possibly 'undefined'.
src/language-vue/parser-vue.js(54,23): error TS2345: Argument of type '(m: string, g: any) => void' is not assignable to parameter of type '(substring: string, ...args: any[]) => string'.
Type 'void' is not assignable to type 'string'.
src/language-vue/parser-vue.js(180,34): error TS2339: Property 'toLowerCase' does not exist on type 'never'.
src/language-vue/parser-vue.js(244,26): error TS2345: Argument of type 'any' is not assignable to parameter of type 'never'.
src/language-vue/parser-vue.js(393,25): error TS2345: Argument of type '{ [x: string]: any; tag: any; attrs: any; unary: any; start: any; children: never[]; }' is not assignable to parameter of type 'never'.
src/language-vue/parser-vue.js(398,23): error TS2345: Argument of type '{ [x: string]: any; tag: any; attrs: any; unary: any; start: any; children: never[]; }' is not assignable to parameter of type '{ [x: string]: any; tag: string; attrs: never[]; unary: boolean; start: number; contentStart: num...'.
Property 'contentStart' is missing in type '{ [x: string]: any; tag: any; attrs: any; unary: any; start: any; children: never[]; }'.
src/language-vue/parser-vue.js(399,9): error TS2322: Type '{ [x: string]: any; tag: any; attrs: any; unary: any; start: any; children: never[]; }' is not assignable to type '{ [x: string]: any; tag: string; attrs: never[]; unary: boolean; start: number; contentStart: num...'.
src/main/core-options.js(51,43): error TS1005: '}' expected.
src/main/core-options.js(63,5): error TS2322: Type '{ cursorOffset: { since: string; category: string; type: "int"; default: number; range: { start: ...' is not assignable to type '{ [name: string]: { since: string; category: string; type: "boolean" | "path" | "int" | "choice";...'.
Property 'cursorOffset' is incompatible with index signature.
Type '{ since: string; category: string; type: "int"; default: number; range: { start: number; end: num...' is not assignable to type '{ since: string; category: string; type: "boolean" | "path" | "int" | "choice"; array: boolean; d...'.
Object literal may only specify known properties, and 'cliCategory' does not exist in type '{ since: string; category: string; type: "boolean" | "path" | "int" | "choice"; array: boolean; d...'.
src/main/parser.js(61,9): error TS2345: Argument of type 'PropertyDescriptor | undefined' is not assignable to parameter of type 'PropertyDescriptor & ThisType<any>'.
Type 'undefined' is not assignable to type 'PropertyDescriptor & ThisType<any>'.
Type 'undefined' is not assignable to type 'PropertyDescriptor'.
src/main/support.js(5,32): error TS2307: Cannot find module '../../package.json'.
src/main/support.js(36,24): error TS2339: Property 'name' does not exist on type 'never'.
src/main/support.js(36,35): error TS2339: Property 'name' does not exist on type 'never'.
src/main/support.js(36,48): error TS2339: Property 'name' does not exist on type 'never'.
src/main/support.js(36,57): error TS2339: Property 'name' does not exist on type 'never'.
Standard error:
@@ -0,0 +1,8 @@
type Constructor = new (...args: any[]) => {};
const Mixin1 = <C extends Constructor>(Base: C) => class extends Base { private _fooPrivate: {}; }
type FooConstructor = typeof Mixin1 extends (a: Constructor) => infer Cls ? Cls : never;
const Mixin2 = <C extends FooConstructor>(Base: C) => class extends Base {};
class C extends Mixin2(Mixin1(Object)) {}
@@ -0,0 +1,26 @@
// @strict: true
interface IListenable {
changeListeners: Function[] | null
observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean): void
}
function notifyListeners<T>(listenable: IListenable, change: T) {
}
export class ObservableValue<T> {
constructor(
public value: T
) {
const newValue: T = value;
const oldValue: any = null;
notifyListeners(this, {
type: "update",
object: this,
newValue,
oldValue
});
}
changeListeners: Function[] | null = [];
observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean) {}
}
@@ -24,3 +24,11 @@ Zet.prototype.add = function(v, o) {
var z = new Zet(1)
z.t = 2
z.u = false
// lookup in typedef should not crash the compiler, even when the type is unknown
/**
* @typedef {Object} A
* @property {T} value
*/
/** @type {A} */
const options = { value: null };
@@ -1,6 +1,7 @@
// @allowJs: true
// @checkJs: true
// @noEmit: true
// @lib: dom,esnext
// @Filename: forgot.js
/**
* @param {T} a
@@ -20,3 +21,8 @@ function g(a) {
return () => a
}
let s = g('hi')()
/**
* @param {Array.<Object>} keyframes - Can't look up types on Element since it's a global in another file. (But it shouldn't crash).
*/
Element.prototype.animate = function(keyframes) {};
@@ -0,0 +1,16 @@
// @noEmit: true
// @allowJs: true
// @checkJs: true
// @noImplicitAny: true
// @strictNullChecks: true
// @Filename: a.js
class Base {
constructor() {
this.p = 1
}
}
class Derived extends Base {
m() {
this.p = 1
}
}
@@ -0,0 +1,17 @@
// @noEmit: true
// @allowJs: true
// @checkJs: true
// @noImplicitAny: true
// @strictNullChecks: true
// @Filename: a.js
class Base {
m() {
this.p = 1
}
}
class Derived extends Base {
m() {
// should be OK, and p should have type number | undefined from its base
this.p = 1
}
}
@@ -0,0 +1,21 @@
// @noEmit: true
// @allowJs: true
// @checkJs: true
// @noImplicitAny: true
// @strictNullChecks: true
// @Filename: a.js
class Base {
m() {
this.p = 1
}
}
class Derived extends Base {
constructor() {
super();
// should be OK, and p should have type number from this assignment
this.p = 1
}
test() {
return this.p
}
}
@@ -0,0 +1,36 @@
// @strict: true
function f1<T extends string | number, U extends string | number>(x: T & U) {
// Combined constraint of 'T & U' is 'string | number'
let y: string | number = x;
}
function f2<T extends string | number | undefined, U extends string | null | undefined>(x: T & U) {
let y1: string | number = x; // Error
let y2: string | null = x; // Error
let y3: string | undefined = x;
let y4: number | null = x; // Error
let y5: number | undefined = x; // Error
let y6: null | undefined = x; // Error
}
type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined
function f3<T extends string | number | undefined>(x: T & (number | object | undefined)) {
const y: number | undefined = x;
}
function f4<T extends string | number>(x: T & (number | object)) {
const y: number = x;
}
function f5<T, U extends keyof T>(x: keyof T & U) {
let y: keyof any = x;
}
// Repro from #23648
type Example<T, U> = { [K in keyof T]: K extends keyof U ? UnexpectedError<K> : NoErrorHere<K> }
type UnexpectedError<T extends PropertyKey> = T
type NoErrorHere<T extends PropertyKey> = T
@@ -568,6 +568,15 @@ type Predicates<TaggedRecord> = {
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]
}
// Repros from #23592
type Example<T extends { [K in keyof T]: { prop: any } }> = { [K in keyof T]: T[K]["prop"] };
type Result = Example<{ a: { prop: string }; b: { prop: number } }>;
type Helper2<T> = { [K in keyof T]: Extract<T[K], { prop: any }> };
type Example2<T> = { [K in keyof Helper2<T>]: Helper2<T>[K]["prop"] };
type Result2 = Example2<{ 1: { prop: string }; 2: { prop: number } }>;
// Repro from #23618
type DBBoolTable<K extends string> = { [k in K]: 0 | 1 }
@@ -0,0 +1,16 @@
// #23734
type ObjType = {
foo: string
baz: string
quux: string
}
const obj: Readonly<ObjType> = {
foo: 'bar',
baz: 'qux',
quux: 'quuz',
}
const { foo, ...rest } = obj
delete rest.baz
@@ -11,6 +11,7 @@ verify.codeFix({
index: 0,
newFileContent: `class C {
foo: number;
method() {
this.foo = 10;
}
@@ -11,6 +11,7 @@ verify.codeFix({
index: 1,
newFileContent: `class C {
[x: string]: number;
method() {
this.foo = 10;
}
@@ -11,6 +11,7 @@ verify.codeFix({
index: 0,
newFileContent: `class C {
static foo: number;
static method() {
this.foo = 10;
}
@@ -17,6 +17,7 @@ verify.codeFixAll({
y(): any {
throw new Error("Method not implemented.");
}
method() {
this.x = 0;
this.y();
@@ -21,6 +21,7 @@ verify.codeFixAll({
y() {
throw new Error("Method not implemented.");
}
constructor() {
this.x = undefined;
}
@@ -0,0 +1,24 @@
/// <reference path='fourslash.ts' />
////abstract class A {
//// abstract m() : void;
////}
////
////class B extends A {
//// // comment
////}
verify.codeFix({
description: "Implement inherited abstract class",
newFileContent:
`abstract class A {
abstract m() : void;
}
class B extends A {
m(): void {
throw new Error("Method not implemented.");
}
// comment
}`,
});
@@ -6,7 +6,7 @@
//// method(a: string): Function;
//// method(a: string | number, b?: string | number): boolean | Function { return a + b as any; }
////}
////class C implements A {[| |]}
////class C implements A { }
verify.codeFix({
description: "Implement interface 'A'",
@@ -1,7 +1,7 @@
/// <reference path='fourslash.ts' />
////interface I<T> { x: T; }
////class C implements I<number> {[| |]}
////class C implements I<number> { }
verify.codeFix({
description: "Implement interface 'I<number>'",
@@ -1,7 +1,7 @@
/// <reference path='fourslash.ts' />
//// class A {[|
//// |]static foo0() {
//// class A {
//// static foo0() {
//// this.m1(1,2,3);
//// A.m2(1,2);
//// this.prop1 = 10;
@@ -12,51 +12,89 @@
verify.codeFix({
description: "Declare static method 'm1'",
index: 0,
newRangeContent: `
newFileContent:
`class A {
static m1(arg0: any, arg1: any, arg2: any): any {
throw new Error("Method not implemented.");
}
`,
static foo0() {
this.m1(1,2,3);
A.m2(1,2);
this.prop1 = 10;
A.prop2 = "asdf";
}
}`,
});
verify.codeFix({
description: "Declare static method 'm2'",
index: 0,
newRangeContent: `
newFileContent:
`class A {
static m2(arg0: any, arg1: any): any {
throw new Error("Method not implemented.");
}
static m1(arg0: any, arg1: any, arg2: any): any {
throw new Error("Method not implemented.");
}
`,
static foo0() {
this.m1(1,2,3);
A.m2(1,2);
this.prop1 = 10;
A.prop2 = "asdf";
}
}`,
});
verify.codeFix({
description: "Declare static property 'prop1'",
index: 0,
newRangeContent: `
newFileContent:
`class A {
static prop1: number;
static m2(arg0: any, arg1: any): any {
throw new Error("Method not implemented.");
}
static m1(arg0: any, arg1: any, arg2: any): any {
throw new Error("Method not implemented.");
}
`,
static foo0() {
this.m1(1,2,3);
A.m2(1,2);
this.prop1 = 10;
A.prop2 = "asdf";
}
}`,
});
verify.codeFix({
description: "Declare static property 'prop2'",
index: 1, // fix at index 0 is to change the spelling to 'prop1'
newRangeContent: `
newFileContent:
`class A {
static prop2: string;
static prop1: number;
static m2(arg0: any, arg1: any): any {
throw new Error("Method not implemented.");
}
static m1(arg0: any, arg1: any, arg2: any): any {
throw new Error("Method not implemented.");
}
`,
static foo0() {
this.m1(1,2,3);
A.m2(1,2);
this.prop1 = 10;
A.prop2 = "asdf";
}
}`,
});
@@ -1,7 +1,7 @@
/// <reference path='fourslash.ts' />
//// class A {[|
//// |]constructor() {
//// class A {
//// constructor() {
//// this.foo1(1,2,3);
//// // 7 type args
//// this.foo2<1,2,3,4,5,6,7>();
@@ -13,38 +13,68 @@
verify.codeFix({
description: "Declare method 'foo1'",
index: 0,
newRangeContent: `
newFileContent:
`class A {
foo1(arg0: any, arg1: any, arg2: any): any {
throw new Error("Method not implemented.");
}
`,
constructor() {
this.foo1(1,2,3);
// 7 type args
this.foo2<1,2,3,4,5,6,7>();
// 8 type args
this.foo3<1,2,3,4,5,6,7,8>();
}
}`,
});
verify.codeFix({
description: "Declare method 'foo2'",
index: 0,
newRangeContent: `
newFileContent:
`class A {
foo2<T, U, V, W, X, Y, Z>(): any {
throw new Error("Method not implemented.");
}
foo1(arg0: any, arg1: any, arg2: any): any {
throw new Error("Method not implemented.");
}
`
constructor() {
this.foo1(1,2,3);
// 7 type args
this.foo2<1,2,3,4,5,6,7>();
// 8 type args
this.foo3<1,2,3,4,5,6,7,8>();
}
}`
});
verify.codeFix({
description: "Declare method 'foo3'",
index: 0,
newRangeContent:`
newFileContent:
`class A {
foo3<T0, T1, T2, T3, T4, T5, T6, T7>(): any {
throw new Error("Method not implemented.");
}
foo2<T, U, V, W, X, Y, Z>(): any {
throw new Error("Method not implemented.");
}
foo1(arg0: any, arg1: any, arg2: any): any {
throw new Error("Method not implemented.");
}
`
constructor() {
this.foo1(1,2,3);
// 7 type args
this.foo2<1,2,3,4,5,6,7>();
// 8 type args
this.foo3<1,2,3,4,5,6,7,8>();
}
}`
});
@@ -0,0 +1,27 @@
/// <reference path="fourslash.ts" />
// @Filename: /src/a.ts
////export const x = 0;
// @Filename: /src/index.ts
////export { x } from "./a";
// @Filename: /0.ts
////x/*0*/
// @Filename: /src/1.ts
////x/*1*/
// @Filename: /src/inner/2.ts
////x/*2*/
for (const [marker, sourceDisplay] of [["0", "./src"], ["1", "./a"], ["2", "../a"]]) {
goTo.marker(marker);
verify.completionListContains({ name: "x", source: "/src/a" }, "const x: 0", "", "const", /*spanIndex*/ undefined, /*hasAction*/ true, { includeCompletionsForModuleExports: true, sourceDisplay });
verify.applyCodeActionFromCompletion(marker, {
name: "x",
source: "/src/a",
description: `Import 'x' from module "${sourceDisplay}"`,
newFileContent: `import { x } from "${sourceDisplay}";\n\nx`,
});
}
@@ -17,6 +17,7 @@ edit.applyRefactor({
public set a(value: string) {
this._a = value;
}
constructor() { }
}`,
});
@@ -17,6 +17,7 @@ edit.applyRefactor({
protected set a(value: string) {
this._a = value;
}
constructor() { }
}`,
});
@@ -17,6 +17,7 @@ edit.applyRefactor({
public set a(value: string) {
this._a = value;
}
constructor() { }
}`,
});
@@ -18,6 +18,7 @@ edit.applyRefactor({
public set a(value: string) {
this._a = value;
}
public a_1: number;
constructor() { }
}`,
+3
View File
@@ -0,0 +1,3 @@
{
"types": ["node"]
}
+17
View File
@@ -0,0 +1,17 @@
{
"compilerOptions": {
"noImplicitAny": false,
"noImplicitThis": false,
"maxNodeModuleJsDepth": 0,
"strict": true,
"noEmit": true,
"allowJs": true,
"checkJs": true,
"types": ["node"],
"lib": ["esnext", "dom"],
"target": "esnext",
"module": "commonjs",
"pretty": false,
},
"include": ["prettier/src"]
}