Merge branch 'master' into mappedTypeInference

# Conflicts:
#	src/compiler/checker.ts
This commit is contained in:
Anders Hejlsberg
2016-11-26 18:39:27 -08:00
15 changed files with 566 additions and 52 deletions
+46 -39
View File
@@ -3205,7 +3205,7 @@ namespace ts {
// right hand expression is of a type parameter type.
if (declaration.parent.parent.kind === SyntaxKind.ForInStatement) {
const indexType = getIndexType(checkNonNullExpression((<ForInStatement>declaration.parent.parent).expression));
return indexType.flags & TypeFlags.Index ? indexType : stringType;
return indexType.flags & (TypeFlags.TypeParameter | TypeFlags.Index) ? indexType : stringType;
}
if (declaration.parent.parent.kind === SyntaxKind.ForOfStatement) {
@@ -5920,6 +5920,11 @@ namespace ts {
getLiteralTypeFromPropertyNames(type);
}
function getIndexTypeOrString(type: Type): Type {
const indexType = getIndexType(type);
return indexType !== neverType ? indexType : stringType;
}
function getTypeFromTypeOperatorNode(node: TypeOperatorNode) {
const links = getNodeLinks(node);
if (!links.resolvedType) {
@@ -6018,8 +6023,7 @@ namespace ts {
// meaningfully access the properties of the object type. In those cases, we first check that the
// index type is assignable to 'keyof T' for the object type.
if (accessNode) {
const keyType = indexType.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(<TypeParameter>indexType) || emptyObjectType : indexType;
if (!isTypeAssignableTo(keyType, getIndexType(objectType))) {
if (!isTypeAssignableTo(indexType, getIndexType(objectType))) {
error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
return unknownType;
}
@@ -8635,33 +8639,6 @@ namespace ts {
}
}
else {
if (getObjectFlags(target) & ObjectFlags.Mapped) {
const constraintType = getConstraintTypeFromMappedType(<MappedType>target);
if (getObjectFlags(source) & ObjectFlags.Mapped) {
// We're inferring from a mapped type to a mapped type, so simply infer from constraint type to
// constraint type and from template type to template type.
inferFromTypes(getConstraintTypeFromMappedType(<MappedType>source), constraintType);
inferFromTypes(getTemplateTypeFromMappedType(<MappedType>source), getTemplateTypeFromMappedType(<MappedType>target));
return;
}
if (constraintType.flags & TypeFlags.TypeParameter) {
// We're inferring from some source type S to a mapped type { [P in T]: X }, where T is a type
// parameter. Infer from 'keyof S' to T and infer from a union of each property type in S to X.
inferFromTypes(getIndexType(source), constraintType);
inferFromTypes(getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)), getTemplateTypeFromMappedType(<MappedType>target));
return;
}
if (constraintType.flags & TypeFlags.Index) {
// We're inferring from some source type S to an isomorphic mapped type { [P in keyof T]: X },
// where T is a type parameter. Use inferTypeForIsomorphicMappedType to infer a suitable source
// type and then infer from that type to T.
const index = indexOf(typeParameters, (<IndexType>constraintType).type);
if (index >= 0 && !typeInferences[index].isFixed) {
inferFromTypes(inferTypeForIsomorphicMappedType(source, <MappedType>target), typeParameters[index]);
}
return;
}
}
source = getApparentType(source);
if (source.flags & TypeFlags.Object) {
if (isInProcess(source, target)) {
@@ -8682,15 +8659,46 @@ namespace ts {
sourceStack[depth] = source;
targetStack[depth] = target;
depth++;
inferFromProperties(source, target);
inferFromSignatures(source, target, SignatureKind.Call);
inferFromSignatures(source, target, SignatureKind.Construct);
inferFromIndexTypes(source, target);
inferFromObjectTypes(source, target);
depth--;
}
}
}
function inferFromObjectTypes(source: Type, target: Type) {
if (getObjectFlags(target) & ObjectFlags.Mapped) {
const constraintType = getConstraintTypeFromMappedType(<MappedType>target);
if (getObjectFlags(source) & ObjectFlags.Mapped) {
// We're inferring from a mapped type to a mapped type, so simply infer from constraint type to
// constraint type and from template type to template type.
inferFromTypes(getConstraintTypeFromMappedType(<MappedType>source), constraintType);
inferFromTypes(getTemplateTypeFromMappedType(<MappedType>source), getTemplateTypeFromMappedType(<MappedType>target));
return;
}
if (constraintType.flags & TypeFlags.TypeParameter) {
// We're inferring from some source type S to a mapped type { [P in T]: X }, where T is a type
// parameter. Infer from 'keyof S' to T and infer from a union of each property type in S to X.
inferFromTypes(getIndexType(source), constraintType);
inferFromTypes(getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)), getTemplateTypeFromMappedType(<MappedType>target));
return;
}
if (constraintType.flags & TypeFlags.Index) {
// We're inferring from some source type S to an isomorphic mapped type { [P in keyof T]: X },
// where T is a type parameter. Use inferTypeForIsomorphicMappedType to infer a suitable source
// type and then infer from that type to T.
const index = indexOf(typeParameters, (<IndexType>constraintType).type);
if (index >= 0 && !typeInferences[index].isFixed) {
inferFromTypes(inferTypeForIsomorphicMappedType(source, <MappedType>target), typeParameters[index]);
}
return;
}
}
inferFromProperties(source, target);
inferFromSignatures(source, target, SignatureKind.Call);
inferFromSignatures(source, target, SignatureKind.Construct);
inferFromIndexTypes(source, target);
}
function inferFromProperties(source: Type, target: Type) {
const properties = getPropertiesOfObjectType(target);
for (const targetProp of properties) {
@@ -14338,7 +14346,7 @@ namespace ts {
// The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
// and the right operand to be of type Any, an object type, or a type parameter type.
// The result is always of the Boolean primitive type.
if (!isTypeAnyOrAllConstituentTypesHaveKind(leftType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
if (!(isTypeComparableTo(leftType, stringType) || isTypeOfKind(leftType, TypeFlags.NumberLike | TypeFlags.ESSymbol))) {
error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
}
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeParameter | TypeFlags.IndexedAccess)) {
@@ -14933,7 +14941,7 @@ namespace ts {
}
contextualType = apparentType;
}
return maybeTypeOfKind(contextualType, TypeFlags.Literal);
return maybeTypeOfKind(contextualType, (TypeFlags.Literal | TypeFlags.Index));
}
return false;
}
@@ -17229,6 +17237,7 @@ namespace ts {
// Grammar checking
checkGrammarForInOrForOfStatement(node);
const rightType = checkNonNullExpression(node.expression);
// TypeScript 1.0 spec (April 2014): 5.4
// In a 'for-in' statement of the form
// for (let VarDecl in Expr) Statement
@@ -17239,7 +17248,6 @@ namespace ts {
if (variable && isBindingPattern(variable.name)) {
error(variable.name, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
}
checkForInOrForOfVariableDeclaration(node);
}
else {
@@ -17252,7 +17260,7 @@ namespace ts {
if (varExpr.kind === SyntaxKind.ArrayLiteralExpression || varExpr.kind === SyntaxKind.ObjectLiteralExpression) {
error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
}
else if (!isTypeAnyOrAllConstituentTypesHaveKind(leftType, TypeFlags.StringLike)) {
else if (!isTypeAssignableTo(getIndexTypeOrString(rightType), leftType)) {
error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any);
}
else {
@@ -17261,7 +17269,6 @@ namespace ts {
}
}
const rightType = checkNonNullExpression(node.expression);
// unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
// in this case error about missing name is already reported - do not report extra one
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeParameter | TypeFlags.IndexedAccess)) {
+2 -2
View File
@@ -1353,13 +1353,13 @@ namespace ts {
// __metadata("design:type", Function),
// __metadata("design:paramtypes", [Object]),
// __metadata("design:returntype", void 0)
// ], C.prototype, "method", undefined);
// ], C.prototype, "method", null);
//
// The emit for an accessor is:
//
// __decorate([
// dec
// ], C.prototype, "accessor", undefined);
// ], C.prototype, "accessor", null);
//
// The emit for a property is:
//
@@ -1,8 +1,6 @@
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(12,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(13,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(14,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(16,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(17,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(19,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(20,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(30,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
@@ -19,7 +17,7 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(43,17): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
==== tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts (19 errors) ====
==== tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts (17 errors) ====
enum E { a }
var x: any;
@@ -42,11 +40,7 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
var ra4 = a4 in x;
var ra5 = null in x;
~~~~
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
var ra6 = undefined in x;
~~~~~~~~~
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
var ra7 = E.a in x;
var ra8 = false in x;
~~~~~
@@ -0,0 +1,81 @@
//// [keyofAndForIn.ts]
// Repro from #12513
function f1<K extends string, T>(obj: { [P in K]: T }, k: K) {
const b = k in obj;
let k1: K;
for (k1 in obj) {
let x1 = obj[k1];
}
for (let k2 in obj) {
let x2 = obj[k2];
}
}
function f2<T>(obj: { [P in keyof T]: T[P] }, k: keyof T) {
const b = k in obj;
let k1: keyof T;
for (k1 in obj) {
let x1 = obj[k1];
}
for (let k2 in obj) {
let x2 = obj[k2];
}
}
function f3<T, K extends keyof T>(obj: { [P in K]: T[P] }, k: K) {
const b = k in obj;
let k1: K;
for (k1 in obj) {
let x1 = obj[k1];
}
for (let k2 in obj) {
let x2 = obj[k2];
}
}
//// [keyofAndForIn.js]
// Repro from #12513
function f1(obj, k) {
var b = k in obj;
var k1;
for (k1 in obj) {
var x1 = obj[k1];
}
for (var k2 in obj) {
var x2 = obj[k2];
}
}
function f2(obj, k) {
var b = k in obj;
var k1;
for (k1 in obj) {
var x1 = obj[k1];
}
for (var k2 in obj) {
var x2 = obj[k2];
}
}
function f3(obj, k) {
var b = k in obj;
var k1;
for (k1 in obj) {
var x1 = obj[k1];
}
for (var k2 in obj) {
var x2 = obj[k2];
}
}
//// [keyofAndForIn.d.ts]
declare function f1<K extends string, T>(obj: {
[P in K]: T;
}, k: K): void;
declare function f2<T>(obj: {
[P in keyof T]: T[P];
}, k: keyof T): void;
declare function f3<T, K extends keyof T>(obj: {
[P in K]: T[P];
}, k: K): void;
@@ -0,0 +1,125 @@
=== tests/cases/conformance/types/keyof/keyofAndForIn.ts ===
// Repro from #12513
function f1<K extends string, T>(obj: { [P in K]: T }, k: K) {
>f1 : Symbol(f1, Decl(keyofAndForIn.ts, 0, 0))
>K : Symbol(K, Decl(keyofAndForIn.ts, 3, 12))
>T : Symbol(T, Decl(keyofAndForIn.ts, 3, 29))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
>P : Symbol(P, Decl(keyofAndForIn.ts, 3, 41))
>K : Symbol(K, Decl(keyofAndForIn.ts, 3, 12))
>T : Symbol(T, Decl(keyofAndForIn.ts, 3, 29))
>k : Symbol(k, Decl(keyofAndForIn.ts, 3, 54))
>K : Symbol(K, Decl(keyofAndForIn.ts, 3, 12))
const b = k in obj;
>b : Symbol(b, Decl(keyofAndForIn.ts, 4, 9))
>k : Symbol(k, Decl(keyofAndForIn.ts, 3, 54))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
let k1: K;
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 5, 7))
>K : Symbol(K, Decl(keyofAndForIn.ts, 3, 12))
for (k1 in obj) {
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 5, 7))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
let x1 = obj[k1];
>x1 : Symbol(x1, Decl(keyofAndForIn.ts, 7, 11))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 5, 7))
}
for (let k2 in obj) {
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 9, 12))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
let x2 = obj[k2];
>x2 : Symbol(x2, Decl(keyofAndForIn.ts, 10, 11))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 3, 33))
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 9, 12))
}
}
function f2<T>(obj: { [P in keyof T]: T[P] }, k: keyof T) {
>f2 : Symbol(f2, Decl(keyofAndForIn.ts, 12, 1))
>T : Symbol(T, Decl(keyofAndForIn.ts, 14, 12))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
>P : Symbol(P, Decl(keyofAndForIn.ts, 14, 23))
>T : Symbol(T, Decl(keyofAndForIn.ts, 14, 12))
>T : Symbol(T, Decl(keyofAndForIn.ts, 14, 12))
>P : Symbol(P, Decl(keyofAndForIn.ts, 14, 23))
>k : Symbol(k, Decl(keyofAndForIn.ts, 14, 45))
>T : Symbol(T, Decl(keyofAndForIn.ts, 14, 12))
const b = k in obj;
>b : Symbol(b, Decl(keyofAndForIn.ts, 15, 9))
>k : Symbol(k, Decl(keyofAndForIn.ts, 14, 45))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
let k1: keyof T;
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 16, 7))
>T : Symbol(T, Decl(keyofAndForIn.ts, 14, 12))
for (k1 in obj) {
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 16, 7))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
let x1 = obj[k1];
>x1 : Symbol(x1, Decl(keyofAndForIn.ts, 18, 11))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 16, 7))
}
for (let k2 in obj) {
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 20, 12))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
let x2 = obj[k2];
>x2 : Symbol(x2, Decl(keyofAndForIn.ts, 21, 11))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 14, 15))
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 20, 12))
}
}
function f3<T, K extends keyof T>(obj: { [P in K]: T[P] }, k: K) {
>f3 : Symbol(f3, Decl(keyofAndForIn.ts, 23, 1))
>T : Symbol(T, Decl(keyofAndForIn.ts, 25, 12))
>K : Symbol(K, Decl(keyofAndForIn.ts, 25, 14))
>T : Symbol(T, Decl(keyofAndForIn.ts, 25, 12))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
>P : Symbol(P, Decl(keyofAndForIn.ts, 25, 42))
>K : Symbol(K, Decl(keyofAndForIn.ts, 25, 14))
>T : Symbol(T, Decl(keyofAndForIn.ts, 25, 12))
>P : Symbol(P, Decl(keyofAndForIn.ts, 25, 42))
>k : Symbol(k, Decl(keyofAndForIn.ts, 25, 58))
>K : Symbol(K, Decl(keyofAndForIn.ts, 25, 14))
const b = k in obj;
>b : Symbol(b, Decl(keyofAndForIn.ts, 26, 9))
>k : Symbol(k, Decl(keyofAndForIn.ts, 25, 58))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
let k1: K;
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 27, 7))
>K : Symbol(K, Decl(keyofAndForIn.ts, 25, 14))
for (k1 in obj) {
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 27, 7))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
let x1 = obj[k1];
>x1 : Symbol(x1, Decl(keyofAndForIn.ts, 29, 11))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
>k1 : Symbol(k1, Decl(keyofAndForIn.ts, 27, 7))
}
for (let k2 in obj) {
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 31, 12))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
let x2 = obj[k2];
>x2 : Symbol(x2, Decl(keyofAndForIn.ts, 32, 11))
>obj : Symbol(obj, Decl(keyofAndForIn.ts, 25, 34))
>k2 : Symbol(k2, Decl(keyofAndForIn.ts, 31, 12))
}
}
@@ -0,0 +1,134 @@
=== tests/cases/conformance/types/keyof/keyofAndForIn.ts ===
// Repro from #12513
function f1<K extends string, T>(obj: { [P in K]: T }, k: K) {
>f1 : <K extends string, T>(obj: { [P in K]: T; }, k: K) => void
>K : K
>T : T
>obj : { [P in K]: T; }
>P : P
>K : K
>T : T
>k : K
>K : K
const b = k in obj;
>b : boolean
>k in obj : boolean
>k : K
>obj : { [P in K]: T; }
let k1: K;
>k1 : K
>K : K
for (k1 in obj) {
>k1 : K
>obj : { [P in K]: T; }
let x1 = obj[k1];
>x1 : T
>obj[k1] : T
>obj : { [P in K]: T; }
>k1 : K
}
for (let k2 in obj) {
>k2 : K
>obj : { [P in K]: T; }
let x2 = obj[k2];
>x2 : T
>obj[k2] : T
>obj : { [P in K]: T; }
>k2 : K
}
}
function f2<T>(obj: { [P in keyof T]: T[P] }, k: keyof T) {
>f2 : <T>(obj: { [P in keyof T]: T[P]; }, k: keyof T) => void
>T : T
>obj : { [P in keyof T]: T[P]; }
>P : P
>T : T
>T : T
>P : P
>k : keyof T
>T : T
const b = k in obj;
>b : boolean
>k in obj : boolean
>k : keyof T
>obj : { [P in keyof T]: T[P]; }
let k1: keyof T;
>k1 : keyof T
>T : T
for (k1 in obj) {
>k1 : keyof T
>obj : { [P in keyof T]: T[P]; }
let x1 = obj[k1];
>x1 : T[keyof T]
>obj[k1] : T[keyof T]
>obj : { [P in keyof T]: T[P]; }
>k1 : keyof T
}
for (let k2 in obj) {
>k2 : keyof T
>obj : { [P in keyof T]: T[P]; }
let x2 = obj[k2];
>x2 : T[keyof T]
>obj[k2] : T[keyof T]
>obj : { [P in keyof T]: T[P]; }
>k2 : keyof T
}
}
function f3<T, K extends keyof T>(obj: { [P in K]: T[P] }, k: K) {
>f3 : <T, K extends keyof T>(obj: { [P in K]: T[P]; }, k: K) => void
>T : T
>K : K
>T : T
>obj : { [P in K]: T[P]; }
>P : P
>K : K
>T : T
>P : P
>k : K
>K : K
const b = k in obj;
>b : boolean
>k in obj : boolean
>k : K
>obj : { [P in K]: T[P]; }
let k1: K;
>k1 : K
>K : K
for (k1 in obj) {
>k1 : K
>obj : { [P in K]: T[P]; }
let x1 = obj[k1];
>x1 : T[K]
>obj[k1] : T[K]
>obj : { [P in K]: T[P]; }
>k1 : K
}
for (let k2 in obj) {
>k2 : K
>obj : { [P in K]: T[P]; }
let x2 = obj[k2];
>x2 : T[K]
>obj[k2] : T[K]
>obj : { [P in K]: T[P]; }
>k2 : K
}
}
@@ -0,0 +1,32 @@
tests/cases/compiler/keyofIsLiteralContexualType.ts(5,9): error TS2322: Type '("a" | "b" | "c")[]' is not assignable to type 'keyof T[]'.
Type '"a" | "b" | "c"' is not assignable to type 'keyof T'.
Type '"a" | "b" | "c"' is not assignable to type '"a" | "b"'.
Type '"c"' is not assignable to type '"a" | "b"'.
Type '"c"' is not assignable to type 'keyof T'.
Type '"c"' is not assignable to type '"a" | "b"'.
tests/cases/compiler/keyofIsLiteralContexualType.ts(13,11): error TS2339: Property 'b' does not exist on type 'Pick<{ a: number; b: number; c: number; }, "a" | "c">'.
==== tests/cases/compiler/keyofIsLiteralContexualType.ts (2 errors) ====
// keyof T is a literal contextual type
function foo<T extends { a: string, b: string }>() {
let a: (keyof T)[] = ["a", "b"];
let b: (keyof T)[] = ["a", "b", "c"];
~
!!! error TS2322: Type '("a" | "b" | "c")[]' is not assignable to type 'keyof T[]'.
!!! error TS2322: Type '"a" | "b" | "c"' is not assignable to type 'keyof T'.
!!! error TS2322: Type '"a" | "b" | "c"' is not assignable to type '"a" | "b"'.
!!! error TS2322: Type '"c"' is not assignable to type '"a" | "b"'.
!!! error TS2322: Type '"c"' is not assignable to type 'keyof T'.
!!! error TS2322: Type '"c"' is not assignable to type '"a" | "b"'.
}
// Repro from #12455
declare function pick<T, K extends keyof T>(obj: T, propNames: K[]): Pick<T, K>;
let x = pick({ a: 10, b: 20, c: 30 }, ["a", "c"]);
let b = x.b; // Error
~
!!! error TS2339: Property 'b' does not exist on type 'Pick<{ a: number; b: number; c: number; }, "a" | "c">'.
@@ -0,0 +1,23 @@
//// [keyofIsLiteralContexualType.ts]
// keyof T is a literal contextual type
function foo<T extends { a: string, b: string }>() {
let a: (keyof T)[] = ["a", "b"];
let b: (keyof T)[] = ["a", "b", "c"];
}
// Repro from #12455
declare function pick<T, K extends keyof T>(obj: T, propNames: K[]): Pick<T, K>;
let x = pick({ a: 10, b: 20, c: 30 }, ["a", "c"]);
let b = x.b; // Error
//// [keyofIsLiteralContexualType.js]
// keyof T is a literal contextual type
function foo() {
var a = ["a", "b"];
var b = ["a", "b", "c"];
}
var x = pick({ a: 10, b: 20, c: 30 }, ["a", "c"]);
var b = x.b; // Error
@@ -0,0 +1,12 @@
//// [mappedTypeInferenceCircularity.ts]
// Repro from #12511
type HTML = { [K in 'div']: Block<HTML> };
type Block<P> = <T>(func: HTML) => {};
declare var h: HTML;
h.div(h);
//// [mappedTypeInferenceCircularity.js]
// Repro from #12511
h.div(h);
@@ -0,0 +1,26 @@
=== tests/cases/compiler/mappedTypeInferenceCircularity.ts ===
// Repro from #12511
type HTML = { [K in 'div']: Block<HTML> };
>HTML : Symbol(HTML, Decl(mappedTypeInferenceCircularity.ts, 0, 0))
>K : Symbol(K, Decl(mappedTypeInferenceCircularity.ts, 2, 15))
>Block : Symbol(Block, Decl(mappedTypeInferenceCircularity.ts, 2, 42))
>HTML : Symbol(HTML, Decl(mappedTypeInferenceCircularity.ts, 0, 0))
type Block<P> = <T>(func: HTML) => {};
>Block : Symbol(Block, Decl(mappedTypeInferenceCircularity.ts, 2, 42))
>P : Symbol(P, Decl(mappedTypeInferenceCircularity.ts, 3, 11))
>T : Symbol(T, Decl(mappedTypeInferenceCircularity.ts, 3, 17))
>func : Symbol(func, Decl(mappedTypeInferenceCircularity.ts, 3, 20))
>HTML : Symbol(HTML, Decl(mappedTypeInferenceCircularity.ts, 0, 0))
declare var h: HTML;
>h : Symbol(h, Decl(mappedTypeInferenceCircularity.ts, 5, 11))
>HTML : Symbol(HTML, Decl(mappedTypeInferenceCircularity.ts, 0, 0))
h.div(h);
>h.div : Symbol(div)
>h : Symbol(h, Decl(mappedTypeInferenceCircularity.ts, 5, 11))
>div : Symbol(div)
>h : Symbol(h, Decl(mappedTypeInferenceCircularity.ts, 5, 11))
@@ -0,0 +1,27 @@
=== tests/cases/compiler/mappedTypeInferenceCircularity.ts ===
// Repro from #12511
type HTML = { [K in 'div']: Block<HTML> };
>HTML : HTML
>K : K
>Block : Block<P>
>HTML : HTML
type Block<P> = <T>(func: HTML) => {};
>Block : Block<P>
>P : P
>T : T
>func : HTML
>HTML : HTML
declare var h: HTML;
>h : HTML
>HTML : HTML
h.div(h);
>h.div(h) : {}
>h.div : Block<HTML>
>h : HTML
>div : Block<HTML>
>h : HTML
@@ -1,5 +1,4 @@
tests/cases/compiler/widenedTypes.ts(2,1): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter.
tests/cases/compiler/widenedTypes.ts(5,1): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
tests/cases/compiler/widenedTypes.ts(6,7): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
tests/cases/compiler/widenedTypes.ts(8,15): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter.
tests/cases/compiler/widenedTypes.ts(10,14): error TS2695: Left side of comma operator is unused and has no side effects.
@@ -12,7 +11,7 @@ tests/cases/compiler/widenedTypes.ts(24,5): error TS2322: Type '{ x: number; y:
Type 'number' is not assignable to type 'string'.
==== tests/cases/compiler/widenedTypes.ts (9 errors) ====
==== tests/cases/compiler/widenedTypes.ts (8 errors) ====
null instanceof (() => { });
~~~~
@@ -20,8 +19,6 @@ tests/cases/compiler/widenedTypes.ts(24,5): error TS2322: Type '{ x: number; y:
({}) instanceof null; // Ok because null is a subtype of function
null in {};
~~~~
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
"" in null;
~~~~
!!! error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter
@@ -0,0 +1,13 @@
// keyof T is a literal contextual type
function foo<T extends { a: string, b: string }>() {
let a: (keyof T)[] = ["a", "b"];
let b: (keyof T)[] = ["a", "b", "c"];
}
// Repro from #12455
declare function pick<T, K extends keyof T>(obj: T, propNames: K[]): Pick<T, K>;
let x = pick({ a: 10, b: 20, c: 30 }, ["a", "c"]);
let b = x.b; // Error
@@ -0,0 +1,7 @@
// Repro from #12511
type HTML = { [K in 'div']: Block<HTML> };
type Block<P> = <T>(func: HTML) => {};
declare var h: HTML;
h.div(h);
@@ -0,0 +1,36 @@
// @declaration: true
// Repro from #12513
function f1<K extends string, T>(obj: { [P in K]: T }, k: K) {
const b = k in obj;
let k1: K;
for (k1 in obj) {
let x1 = obj[k1];
}
for (let k2 in obj) {
let x2 = obj[k2];
}
}
function f2<T>(obj: { [P in keyof T]: T[P] }, k: keyof T) {
const b = k in obj;
let k1: keyof T;
for (k1 in obj) {
let x1 = obj[k1];
}
for (let k2 in obj) {
let x2 = obj[k2];
}
}
function f3<T, K extends keyof T>(obj: { [P in K]: T[P] }, k: K) {
const b = k in obj;
let k1: K;
for (k1 in obj) {
let x1 = obj[k1];
}
for (let k2 in obj) {
let x2 = obj[k2];
}
}