Merge branch 'master' into fixIndexedAccessWildcard

# Conflicts:
#	tests/baselines/reference/conditionalTypes1.errors.txt
#	tests/baselines/reference/conditionalTypes1.js
#	tests/baselines/reference/conditionalTypes1.symbols
#	tests/baselines/reference/conditionalTypes1.types
#	tests/cases/conformance/types/conditional/conditionalTypes1.ts
This commit is contained in:
Anders Hejlsberg 2018-02-10 17:29:06 -08:00
commit 318e53cecb
10 changed files with 1047 additions and 574 deletions

View File

@ -2,7 +2,7 @@
Thank you for submitting a pull request!
Here's a checklist you might find useful.
[ ] There is an associated issue that is labelled
[ ] There is an associated issue that is labeled
'Bug' or 'help wanted' or is in the Community milestone
[ ] Code is up-to-date with the `master` branch
[ ] You've successfully run `jake runtests` locally

View File

@ -6096,11 +6096,13 @@ namespace ts {
// with its constraint. We do this because if the constraint is a union type it will be distributed
// over the conditional type and possibly reduced. For example, 'T extends undefined ? never : T'
// removes 'undefined' from T.
const checkType = type.checkType;
if (checkType.flags & TypeFlags.TypeParameter) {
const constraint = getConstraintOfTypeParameter(<TypeParameter>checkType);
if (isDistributiveConditionalType(type)) {
const constraint = getConstraintOfType(type.checkType);
if (constraint) {
return instantiateType(type, createTypeMapper([<TypeParameter>checkType], [constraint]));
const target = type.target || type;
const mapper = createTypeMapper([<TypeParameter>target.checkType], [constraint]);
const combinedMapper = type.mapper ? combineTypeMappers(mapper, type.mapper) : mapper;
return instantiateType(target, combinedMapper);
}
}
return undefined;
@ -8237,6 +8239,10 @@ namespace ts {
return result;
}
function isDistributiveConditionalType(type: ConditionalType) {
return !!((type.target || type).checkType.flags & TypeFlags.TypeParameter);
}
function getInferTypeParameters(node: ConditionalTypeNode): TypeParameter[] {
let result: TypeParameter[];
if (node.locals) {
@ -8849,9 +8855,9 @@ namespace ts {
// Check if we have a conditional type where the check type is a naked type parameter. If so,
// the conditional type is distributive over union types and when T is instantiated to a union
// type A | B, we produce (A extends U ? X : Y) | (B extends U ? X : Y).
const checkType = target.checkType;
if (checkType.flags & TypeFlags.TypeParameter) {
const instantiatedType = combinedMapper(<TypeParameter>checkType);
if (isDistributiveConditionalType(target)) {
const checkType = <TypeParameter>target.checkType;
const instantiatedType = combinedMapper(checkType);
if (checkType !== instantiatedType && instantiatedType.flags & TypeFlags.Union) {
return mapType(instantiatedType, t => instantiateConditionalType(target, createReplacementMapper(checkType, t, combinedMapper)));
}
@ -9628,17 +9634,43 @@ namespace ts {
function isIdenticalTo(source: Type, target: Type): Ternary {
let result: Ternary;
if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) {
const flags = source.flags & target.flags;
if (flags & TypeFlags.Object) {
return recursiveTypeRelatedTo(source, target, /*reportErrors*/ false);
}
if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union ||
source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) {
if (flags & (TypeFlags.Union | TypeFlags.Intersection)) {
if (result = eachTypeRelatedToSomeType(<UnionOrIntersectionType>source, <UnionOrIntersectionType>target)) {
if (result &= eachTypeRelatedToSomeType(<UnionOrIntersectionType>target, <UnionOrIntersectionType>source)) {
return result;
}
}
}
if (flags & TypeFlags.Index) {
return isRelatedTo((<IndexType>source).type, (<IndexType>target).type, /*reportErrors*/ false);
}
if (flags & TypeFlags.IndexedAccess) {
if (result = isRelatedTo((<IndexedAccessType>source).objectType, (<IndexedAccessType>target).objectType, /*reportErrors*/ false)) {
if (result &= isRelatedTo((<IndexedAccessType>source).indexType, (<IndexedAccessType>target).indexType, /*reportErrors*/ false)) {
return result;
}
}
}
if (flags & TypeFlags.Conditional) {
if (result = isRelatedTo((<ConditionalType>source).checkType, (<ConditionalType>target).checkType, /*reportErrors*/ false)) {
if (result &= isRelatedTo((<ConditionalType>source).extendsType, (<ConditionalType>target).extendsType, /*reportErrors*/ false)) {
if (result &= isRelatedTo((<ConditionalType>source).trueType, (<ConditionalType>target).trueType, /*reportErrors*/ false)) {
if (result &= isRelatedTo((<ConditionalType>source).falseType, (<ConditionalType>target).falseType, /*reportErrors*/ false)) {
if (isDistributiveConditionalType(<ConditionalType>source) === isDistributiveConditionalType(<ConditionalType>target)) {
return result;
}
}
}
}
}
}
if (flags & TypeFlags.Substitution) {
return isRelatedTo((<SubstitutionType>source).substitute, (<SubstitutionType>target).substitute, /*reportErrors*/ false);
}
return Ternary.False;
}
@ -10024,7 +10056,19 @@ namespace ts {
}
}
}
if (result = isRelatedTo(getDefaultConstraintOfConditionalType(<ConditionalType>source), target, reportErrors)) {
if (target.flags & TypeFlags.Conditional) {
if (isTypeIdenticalTo((<ConditionalType>source).checkType, (<ConditionalType>target).checkType) &&
isTypeIdenticalTo((<ConditionalType>source).extendsType, (<ConditionalType>target).extendsType)) {
if (result = isRelatedTo((<ConditionalType>source).trueType, (<ConditionalType>target).trueType, reportErrors)) {
result &= isRelatedTo((<ConditionalType>source).falseType, (<ConditionalType>target).falseType, reportErrors);
}
if (result) {
errorInfo = saveErrorInfo;
return result;
}
}
}
else if (result = isRelatedTo(getDefaultConstraintOfConditionalType(<ConditionalType>source), target, reportErrors)) {
errorInfo = saveErrorInfo;
return result;
}

View File

@ -92,6 +92,9 @@ namespace ts.formatting {
rule("SpaceBetweenCloseBraceAndWhile", SyntaxKind.CloseBraceToken, SyntaxKind.WhileKeyword, [isNonJsxSameLineTokenContext], RuleAction.Space),
rule("NoSpaceBetweenEmptyBraceBrackets", SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, [isNonJsxSameLineTokenContext, isObjectContext], RuleAction.Delete),
// Add a space after control dec context if the next character is an open bracket ex: 'if (false)[a, b] = [1, 2];' -> 'if (false) [a, b] = [1, 2];'
rule("SpaceAfterConditionalClosingParen", SyntaxKind.CloseParenToken, SyntaxKind.OpenBracketToken, [isControlDeclContext], RuleAction.Space),
rule("NoSpaceBetweenFunctionKeywordAndStar", SyntaxKind.FunctionKeyword, SyntaxKind.AsteriskToken, [isFunctionDeclarationOrFunctionExpressionContext], RuleAction.Delete),
rule("SpaceAfterStarInGeneratorDeclaration", SyntaxKind.AsteriskToken, [SyntaxKind.Identifier, SyntaxKind.OpenParenToken], [isFunctionDeclarationOrFunctionExpressionContext], RuleAction.Space),
@ -162,6 +165,7 @@ namespace ts.formatting {
SyntaxKind.TypeKeyword,
SyntaxKind.FromKeyword,
SyntaxKind.KeyOfKeyword,
SyntaxKind.InferKeyword,
],
anyToken,
[isNonJsxSameLineTokenContext],

View File

@ -8,9 +8,15 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(18,9): error TS23
tests/cases/conformance/types/conditional/conditionalTypes1.ts(24,5): error TS2322: Type 'Partial<T>[keyof T]' is not assignable to type 'NonNullable<Partial<T>[keyof T]>'.
Type 'T[keyof T] | undefined' is not assignable to type 'NonNullable<Partial<T>[keyof T]>'.
Type 'undefined' is not assignable to type 'NonNullable<Partial<T>[keyof T]>'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(96,5): error TS2322: Type 'Pick<T, { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]>' is not assignable to type 'T'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(97,5): error TS2322: Type 'Pick<T, { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]>' is not assignable to type 'T'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(99,5): error TS2322: Type 'Pick<T, { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]>' is not assignable to type 'Pick<T, { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]>'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(29,5): error TS2322: Type 'T["x"]' is not assignable to type 'NonNullable<T["x"]>'.
Type 'string | undefined' is not assignable to type 'NonNullable<T["x"]>'.
Type 'undefined' is not assignable to type 'NonNullable<T["x"]>'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(30,9): error TS2322: Type 'T["x"]' is not assignable to type 'string'.
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(103,5): error TS2322: Type 'Pick<T, { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]>' is not assignable to type 'T'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(104,5): error TS2322: Type 'Pick<T, { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]>' is not assignable to type 'T'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(106,5): error TS2322: Type 'Pick<T, { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]>' is not assignable to type 'Pick<T, { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]>'.
Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'.
Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'.
Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'.
@ -18,8 +24,8 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(99,5): error TS23
Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(101,5): error TS2322: Type 'Pick<T, { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]>' is not assignable to type 'Pick<T, { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]>'.
Type 'keyof T' is not assignable to type 'never'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(108,5): error TS2322: Type 'Pick<T, { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]>' is not assignable to type 'Pick<T, { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]>'.
Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'.
Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'.
Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'.
@ -27,41 +33,43 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(101,5): error TS2
Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(107,5): error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'.
Type 'keyof T' is not assignable to type 'never'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(114,5): error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'.
Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(108,5): error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(115,5): error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'.
Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'.
Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'.
Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(109,5): error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'.
Type 'keyof T' is not assignable to type 'never'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(116,5): error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'.
Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(110,5): error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(117,5): error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'.
Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'.
Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'.
Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(127,10): error TS2540: Cannot assign to 'id' because it is a constant or a read-only property.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(128,5): error TS2542: Index signature in type 'DeepReadonlyArray<Part>' only permits reading.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(129,22): error TS2540: Cannot assign to 'id' because it is a constant or a read-only property.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(130,10): error TS2339: Property 'updatePart' does not exist on type 'DeepReadonlyObject<Part>'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(152,5): error TS2322: Type 'ZeroOf<T>' is not assignable to type 'T'.
Type 'keyof T' is not assignable to type 'never'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(134,10): error TS2540: Cannot assign to 'id' because it is a constant or a read-only property.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(135,5): error TS2542: Index signature in type 'DeepReadonlyArray<Part>' only permits reading.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(136,22): error TS2540: Cannot assign to 'id' because it is a constant or a read-only property.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(137,10): error TS2339: Property 'updatePart' does not exist on type 'DeepReadonlyObject<Part>'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(159,5): error TS2322: Type 'ZeroOf<T>' is not assignable to type 'T'.
Type '0 | (T extends string ? "" : false)' is not assignable to type 'T'.
Type '0' is not assignable to type 'T'.
Type '"" | 0' is not assignable to type 'T'.
Type '""' is not assignable to type 'T'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(153,5): error TS2322: Type 'T' is not assignable to type 'ZeroOf<T>'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(160,5): error TS2322: Type 'T' is not assignable to type 'ZeroOf<T>'.
Type 'string | number' is not assignable to type 'ZeroOf<T>'.
Type 'string' is not assignable to type 'ZeroOf<T>'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(243,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'z' must be of type 'T1', but here has type 'Foo<T & U>'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(250,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'z' must be of type 'T1', but here has type 'Foo<T & U>'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(275,43): error TS2322: Type 'T95<U>' is not assignable to type 'T94<U>'.
Type 'boolean' is not assignable to type 'true'.
==== tests/cases/conformance/types/conditional/conditionalTypes1.ts (19 errors) ====
==== tests/cases/conformance/types/conditional/conditionalTypes1.ts (22 errors) ====
type T00 = Exclude<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "b" | "d"
type T01 = Extract<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "a" | "c"
@ -102,6 +110,21 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(243,9): error TS2
!!! error TS2322: Type 'undefined' is not assignable to type 'NonNullable<Partial<T>[keyof T]>'.
}
function f4<T extends { x: string | undefined }>(x: T["x"], y: NonNullable<T["x"]>) {
x = y;
y = x; // Error
~
!!! error TS2322: Type 'T["x"]' is not assignable to type 'NonNullable<T["x"]>'.
!!! error TS2322: Type 'string | undefined' is not assignable to type 'NonNullable<T["x"]>'.
!!! error TS2322: Type 'undefined' is not assignable to type 'NonNullable<T["x"]>'.
let s1: string = x; // Error
~~
!!! error TS2322: Type 'T["x"]' is not assignable to type 'string'.
!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'.
!!! error TS2322: Type 'undefined' is not assignable to type 'string'.
let s2: string = y;
}
type Options = { k: "a", a: number } | { k: "b", b: string } | { k: "c", c: boolean };
type T10 = Exclude<Options, { k: "a" | "b" }>; // { k: "c", c: boolean }
@ -113,8 +136,8 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(243,9): error TS2
type T14 = Exclude<Options, { q: "a" }>; // Options
type T15 = Extract<Options, { q: "a" }>; // never
declare function f4<T extends Options, K extends string>(p: K): Extract<T, { k: K }>;
let x0 = f4("a"); // { k: "a", a: number }
declare function f5<T extends Options, K extends string>(p: K): Extract<T, { k: K }>;
let x0 = f5("a"); // { k: "a", a: number }
type OptionsOfKind<K extends Options["k"]> = Extract<Options, { k: K }>;
@ -188,7 +211,7 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(243,9): error TS2
!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'never'.
z = x;
z = y; // Error
~
@ -200,7 +223,7 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(243,9): error TS2
!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'never'.
}
function f8<T>(x: keyof T, y: FunctionPropertyNames<T>, z: NonFunctionPropertyNames<T>) {
@ -218,7 +241,7 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(243,9): error TS2
!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'never'.
z = x; // Error
~
!!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'.
@ -231,7 +254,7 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(243,9): error TS2
!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'never'.
}
type DeepReadonly<T> =
@ -394,9 +417,29 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(243,9): error TS2
var z: T2;
}
// Repro from #21823
type T90<T> = T extends 0 ? 0 : () => 0;
type T91<T> = T extends 0 ? 0 : () => 0;
const f40 = <U>(a: T90<U>): T91<U> => a;
const f41 = <U>(a: T91<U>): T90<U> => a;
type T92<T> = T extends () => 0 ? () => 1 : () => 2;
type T93<T> = T extends () => 0 ? () => 1 : () => 2;
const f42 = <U>(a: T92<U>): T93<U> => a;
const f43 = <U>(a: T93<U>): T92<U> => a;
type T94<T> = T extends string ? true : 42;
type T95<T> = T extends string ? boolean : number;
const f44 = <U>(value: T94<U>): T95<U> => value;
const f45 = <U>(value: T95<U>): T94<U> => value; // Error
~~~~~
!!! error TS2322: Type 'T95<U>' is not assignable to type 'T94<U>'.
!!! error TS2322: Type 'boolean' is not assignable to type 'true'.
// Repro from #21863
function f40() {
function f50() {
type Eq<T, U> = T extends U ? U extends T ? true : false : false;
type If<S, T, U> = S extends false ? U : T;
type Omit<T extends object> = { [P in keyof T]: If<Eq<T[P], never>, never, P>; }[keyof T];

View File

@ -25,6 +25,13 @@ function f3<T>(x: Partial<T>[keyof T], y: NonNullable<Partial<T>[keyof T]>) {
y = x; // Error
}
function f4<T extends { x: string | undefined }>(x: T["x"], y: NonNullable<T["x"]>) {
x = y;
y = x; // Error
let s1: string = x; // Error
let s2: string = y;
}
type Options = { k: "a", a: number } | { k: "b", b: string } | { k: "c", c: boolean };
type T10 = Exclude<Options, { k: "a" | "b" }>; // { k: "c", c: boolean }
@ -36,8 +43,8 @@ type T13 = Extract<Options, { k: "a" } | { k: "b" }>; // { k: "a", a: number }
type T14 = Exclude<Options, { q: "a" }>; // Options
type T15 = Extract<Options, { q: "a" }>; // never
declare function f4<T extends Options, K extends string>(p: K): Extract<T, { k: K }>;
let x0 = f4("a"); // { k: "a", a: number }
declare function f5<T extends Options, K extends string>(p: K): Extract<T, { k: K }>;
let x0 = f5("a"); // { k: "a", a: number }
type OptionsOfKind<K extends Options["k"]> = Extract<Options, { k: K }>;
@ -251,9 +258,26 @@ function f33<T, U>() {
var z: T2;
}
// Repro from #21823
type T90<T> = T extends 0 ? 0 : () => 0;
type T91<T> = T extends 0 ? 0 : () => 0;
const f40 = <U>(a: T90<U>): T91<U> => a;
const f41 = <U>(a: T91<U>): T90<U> => a;
type T92<T> = T extends () => 0 ? () => 1 : () => 2;
type T93<T> = T extends () => 0 ? () => 1 : () => 2;
const f42 = <U>(a: T92<U>): T93<U> => a;
const f43 = <U>(a: T93<U>): T92<U> => a;
type T94<T> = T extends string ? true : 42;
type T95<T> = T extends string ? boolean : number;
const f44 = <U>(value: T94<U>): T95<U> => value;
const f45 = <U>(value: T95<U>): T94<U> => value; // Error
// Repro from #21863
function f40() {
function f50() {
type Eq<T, U> = T extends U ? U extends T ? true : false : false;
type If<S, T, U> = S extends false ? U : T;
type Omit<T extends object> = { [P in keyof T]: If<Eq<T[P], never>, never, P>; }[keyof T];
@ -279,7 +303,13 @@ function f3(x, y) {
x = y;
y = x; // Error
}
var x0 = f4("a"); // { k: "a", a: number }
function f4(x, y) {
x = y;
y = x; // Error
var s1 = x; // Error
var s2 = y;
}
var x0 = f5("a"); // { k: "a", a: number }
function f7(x, y, z) {
x = y; // Error
x = z; // Error
@ -336,8 +366,14 @@ function f33() {
var z;
var z;
}
var f40 = function (a) { return a; };
var f41 = function (a) { return a; };
var f42 = function (a) { return a; };
var f43 = function (a) { return a; };
var f44 = function (value) { return value; };
var f45 = function (value) { return value; }; // Error
// Repro from #21863
function f40() {
function f50() {
}
@ -351,6 +387,9 @@ declare type T05 = NonNullable<(() => string) | string[] | null | undefined>;
declare function f1<T>(x: T, y: NonNullable<T>): void;
declare function f2<T extends string | undefined>(x: T, y: NonNullable<T>): void;
declare function f3<T>(x: Partial<T>[keyof T], y: NonNullable<Partial<T>[keyof T]>): void;
declare function f4<T extends {
x: string | undefined;
}>(x: T["x"], y: NonNullable<T["x"]>): void;
declare type Options = {
k: "a";
a: number;
@ -383,7 +422,7 @@ declare type T14 = Exclude<Options, {
declare type T15 = Extract<Options, {
q: "a";
}>;
declare function f4<T extends Options, K extends string>(p: K): Extract<T, {
declare function f5<T extends Options, K extends string>(p: K): Extract<T, {
k: K;
}>;
declare let x0: {
@ -509,4 +548,16 @@ declare const convert2: <T>(value: Foo<T>) => Foo<T>;
declare function f31<T>(): void;
declare function f32<T, U>(): void;
declare function f33<T, U>(): void;
declare function f40(): void;
declare type T90<T> = T extends 0 ? 0 : () => 0;
declare type T91<T> = T extends 0 ? 0 : () => 0;
declare const f40: <U>(a: T90<U>) => T91<U>;
declare const f41: <U>(a: T91<U>) => T90<U>;
declare type T92<T> = T extends () => 0 ? () => 1 : () => 2;
declare type T93<T> = T extends () => 0 ? () => 1 : () => 2;
declare const f42: <U>(a: T92<U>) => T93<U>;
declare const f43: <U>(a: T93<U>) => T92<U>;
declare type T94<T> = T extends string ? true : 42;
declare type T95<T> = T extends string ? boolean : number;
declare const f44: <U>(value: T94<U>) => T95<U>;
declare const f45: <U>(value: T95<U>) => T94<U>;
declare function f50(): void;

File diff suppressed because it is too large Load Diff

View File

@ -98,6 +98,35 @@ function f3<T>(x: Partial<T>[keyof T], y: NonNullable<Partial<T>[keyof T]>) {
>x : Partial<T>[keyof T]
}
function f4<T extends { x: string | undefined }>(x: T["x"], y: NonNullable<T["x"]>) {
>f4 : <T extends { x: string | undefined; }>(x: T["x"], y: NonNullable<T["x"]>) => void
>T : T
>x : string | undefined
>x : T["x"]
>T : T
>y : NonNullable<T["x"]>
>NonNullable : NonNullable<T>
>T : T
x = y;
>x = y : NonNullable<T["x"]>
>x : T["x"]
>y : NonNullable<T["x"]>
y = x; // Error
>y = x : T["x"]
>y : NonNullable<T["x"]>
>x : T["x"]
let s1: string = x; // Error
>s1 : string
>x : T["x"]
let s2: string = y;
>s2 : string
>y : NonNullable<T["x"]>
}
type Options = { k: "a", a: number } | { k: "b", b: string } | { k: "c", c: boolean };
>Options : Options
>k : "a"
@ -145,8 +174,8 @@ type T15 = Extract<Options, { q: "a" }>; // never
>Options : Options
>q : "a"
declare function f4<T extends Options, K extends string>(p: K): Extract<T, { k: K }>;
>f4 : <T extends Options, K extends string>(p: K) => Extract<T, { k: K; }>
declare function f5<T extends Options, K extends string>(p: K): Extract<T, { k: K }>;
>f5 : <T extends Options, K extends string>(p: K) => Extract<T, { k: K; }>
>T : T
>Options : Options
>K : K
@ -157,10 +186,10 @@ declare function f4<T extends Options, K extends string>(p: K): Extract<T, { k:
>k : K
>K : K
let x0 = f4("a"); // { k: "a", a: number }
let x0 = f5("a"); // { k: "a", a: number }
>x0 : { k: "a"; a: number; }
>f4("a") : { k: "a"; a: number; }
>f4 : <T extends Options, K extends string>(p: K) => Extract<T, { k: K; }>
>f5("a") : { k: "a"; a: number; }
>f5 : <T extends Options, K extends string>(p: K) => Extract<T, { k: K; }>
>"a" : "a"
type OptionsOfKind<K extends Options["k"]> = Extract<Options, { k: K }>;
@ -1080,10 +1109,109 @@ function f33<T, U>() {
>T2 : Foo<T & U>
}
// Repro from #21823
type T90<T> = T extends 0 ? 0 : () => 0;
>T90 : T90<T>
>T : T
>T : T
type T91<T> = T extends 0 ? 0 : () => 0;
>T91 : T91<T>
>T : T
>T : T
const f40 = <U>(a: T90<U>): T91<U> => a;
>f40 : <U>(a: T90<U>) => T91<U>
><U>(a: T90<U>): T91<U> => a : <U>(a: T90<U>) => T91<U>
>U : U
>a : T90<U>
>T90 : T90<T>
>U : U
>T91 : T91<T>
>U : U
>a : T90<U>
const f41 = <U>(a: T91<U>): T90<U> => a;
>f41 : <U>(a: T91<U>) => T90<U>
><U>(a: T91<U>): T90<U> => a : <U>(a: T91<U>) => T90<U>
>U : U
>a : T91<U>
>T91 : T91<T>
>U : U
>T90 : T90<T>
>U : U
>a : T91<U>
type T92<T> = T extends () => 0 ? () => 1 : () => 2;
>T92 : T92<T>
>T : T
>T : T
type T93<T> = T extends () => 0 ? () => 1 : () => 2;
>T93 : T93<T>
>T : T
>T : T
const f42 = <U>(a: T92<U>): T93<U> => a;
>f42 : <U>(a: T92<U>) => T93<U>
><U>(a: T92<U>): T93<U> => a : <U>(a: T92<U>) => T93<U>
>U : U
>a : T92<U>
>T92 : T92<T>
>U : U
>T93 : T93<T>
>U : U
>a : T92<U>
const f43 = <U>(a: T93<U>): T92<U> => a;
>f43 : <U>(a: T93<U>) => T92<U>
><U>(a: T93<U>): T92<U> => a : <U>(a: T93<U>) => T92<U>
>U : U
>a : T93<U>
>T93 : T93<T>
>U : U
>T92 : T92<T>
>U : U
>a : T93<U>
type T94<T> = T extends string ? true : 42;
>T94 : T94<T>
>T : T
>T : T
>true : true
type T95<T> = T extends string ? boolean : number;
>T95 : T95<T>
>T : T
>T : T
const f44 = <U>(value: T94<U>): T95<U> => value;
>f44 : <U>(value: T94<U>) => T95<U>
><U>(value: T94<U>): T95<U> => value : <U>(value: T94<U>) => T95<U>
>U : U
>value : T94<U>
>T94 : T94<T>
>U : U
>T95 : T95<T>
>U : U
>value : T94<U>
const f45 = <U>(value: T95<U>): T94<U> => value; // Error
>f45 : <U>(value: T95<U>) => T94<U>
><U>(value: T95<U>): T94<U> => value : <U>(value: T95<U>) => T94<U>
>U : U
>value : T95<U>
>T95 : T95<T>
>U : U
>T94 : T94<T>
>U : U
>value : T95<U>
// Repro from #21863
function f40() {
>f40 : () => void
function f50() {
>f50 : () => void
type Eq<T, U> = T extends U ? U extends T ? true : false : false;
>Eq : T extends U ? U extends T ? true : false : false

View File

@ -27,6 +27,13 @@ function f3<T>(x: Partial<T>[keyof T], y: NonNullable<Partial<T>[keyof T]>) {
y = x; // Error
}
function f4<T extends { x: string | undefined }>(x: T["x"], y: NonNullable<T["x"]>) {
x = y;
y = x; // Error
let s1: string = x; // Error
let s2: string = y;
}
type Options = { k: "a", a: number } | { k: "b", b: string } | { k: "c", c: boolean };
type T10 = Exclude<Options, { k: "a" | "b" }>; // { k: "c", c: boolean }
@ -38,8 +45,8 @@ type T13 = Extract<Options, { k: "a" } | { k: "b" }>; // { k: "a", a: number }
type T14 = Exclude<Options, { q: "a" }>; // Options
type T15 = Extract<Options, { q: "a" }>; // never
declare function f4<T extends Options, K extends string>(p: K): Extract<T, { k: K }>;
let x0 = f4("a"); // { k: "a", a: number }
declare function f5<T extends Options, K extends string>(p: K): Extract<T, { k: K }>;
let x0 = f5("a"); // { k: "a", a: number }
type OptionsOfKind<K extends Options["k"]> = Extract<Options, { k: K }>;
@ -253,9 +260,26 @@ function f33<T, U>() {
var z: T2;
}
// Repro from #21823
type T90<T> = T extends 0 ? 0 : () => 0;
type T91<T> = T extends 0 ? 0 : () => 0;
const f40 = <U>(a: T90<U>): T91<U> => a;
const f41 = <U>(a: T91<U>): T90<U> => a;
type T92<T> = T extends () => 0 ? () => 1 : () => 2;
type T93<T> = T extends () => 0 ? () => 1 : () => 2;
const f42 = <U>(a: T92<U>): T93<U> => a;
const f43 = <U>(a: T93<U>): T92<U> => a;
type T94<T> = T extends string ? true : 42;
type T95<T> = T extends string ? boolean : number;
const f44 = <U>(value: T94<U>): T95<U> => value;
const f45 = <U>(value: T95<U>): T94<U> => value; // Error
// Repro from #21863
function f40() {
function f50() {
type Eq<T, U> = T extends U ? U extends T ? true : false : false;
type If<S, T, U> = S extends false ? U : T;
type Omit<T extends object> = { [P in keyof T]: If<Eq<T[P], never>, never, P>; }[keyof T];

View File

@ -0,0 +1,15 @@
/// <reference path='fourslash.ts'/>
//// let a, b;
//// /*1*/if (false)[a, b] = [1, 2];
//// /*2*/if (true) [a, b] = [1, 2];
//// /*3*/var a = [1, 2, 3].map(num => num) [0];
format.document();
goTo.marker("1");
verify.currentLineContentIs("if (false) [a, b] = [1, 2];");
goTo.marker("2");
verify.currentLineContentIs("if (true) [a, b] = [1, 2];");
goTo.marker("3");
verify.currentLineContentIs("var a = [1, 2, 3].map(num => num)[0];");

View File

@ -0,0 +1,45 @@
/// <reference path='fourslash.ts'/>
////
/////*L1*/type C<T> = T extends Array<infer U> ? U : never;
////
/////*L2*/ type C < T > = T extends Array < infer U > ? U : never ;
////
/////*L3*/type C<T> = T extends Array<infer U> ? U : T;
////
/////*L4*/ type C < T > = T extends Array < infer U > ? U : T ;
////
/////*L5*/type Foo<T> = T extends { a: infer U, b: infer U } ? U : never;
////
/////*L6*/ type Foo < T > = T extends { a : infer U , b : infer U } ? U : never ;
////
/////*L7*/type Bar<T> = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never;
////
/////*L8*/ type Bar < T > = T extends { a : (x : infer U ) => void , b : (x : infer U ) => void } ? U : never ;
////
format.document();
goTo.marker("L1");
verify.currentLineContentIs("type C<T> = T extends Array<infer U> ? U : never;");
goTo.marker("L2");
verify.currentLineContentIs("type C<T> = T extends Array<infer U> ? U : never;");
goTo.marker("L3");
verify.currentLineContentIs("type C<T> = T extends Array<infer U> ? U : T;");
goTo.marker("L4");
verify.currentLineContentIs("type C<T> = T extends Array<infer U> ? U : T;");
goTo.marker("L5");
verify.currentLineContentIs("type Foo<T> = T extends { a: infer U, b: infer U } ? U : never;");
goTo.marker("L6");
verify.currentLineContentIs("type Foo<T> = T extends { a: infer U, b: infer U } ? U : never;");
goTo.marker("L7");
verify.currentLineContentIs("type Bar<T> = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never;");
goTo.marker("L8");
verify.currentLineContentIs("type Bar<T> = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never;");