mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-17 00:34:47 -05:00
* Merge pull request #30856 from Microsoft/nonInferrableType Add a proper non-inferrable type * Merge pull request #30963 from Microsoft/fixObjectFlagsPropagation Fix object flags propagation
This commit is contained in:
@@ -403,10 +403,10 @@ namespace ts {
|
||||
const wildcardType = createIntrinsicType(TypeFlags.Any, "any");
|
||||
const errorType = createIntrinsicType(TypeFlags.Any, "error");
|
||||
const unknownType = createIntrinsicType(TypeFlags.Unknown, "unknown");
|
||||
const undefinedType = createNullableType(TypeFlags.Undefined, "undefined", 0);
|
||||
const undefinedWideningType = strictNullChecks ? undefinedType : createNullableType(TypeFlags.Undefined, "undefined", ObjectFlags.ContainsWideningType);
|
||||
const nullType = createNullableType(TypeFlags.Null, "null", 0);
|
||||
const nullWideningType = strictNullChecks ? nullType : createNullableType(TypeFlags.Null, "null", ObjectFlags.ContainsWideningType);
|
||||
const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined");
|
||||
const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined, "undefined", ObjectFlags.ContainsWideningType);
|
||||
const nullType = createIntrinsicType(TypeFlags.Null, "null");
|
||||
const nullWideningType = strictNullChecks ? nullType : createIntrinsicType(TypeFlags.Null, "null", ObjectFlags.ContainsWideningType);
|
||||
const stringType = createIntrinsicType(TypeFlags.String, "string");
|
||||
const numberType = createIntrinsicType(TypeFlags.Number, "number");
|
||||
const bigintType = createIntrinsicType(TypeFlags.BigInt, "bigint");
|
||||
@@ -432,6 +432,7 @@ namespace ts {
|
||||
const voidType = createIntrinsicType(TypeFlags.Void, "void");
|
||||
const neverType = createIntrinsicType(TypeFlags.Never, "never");
|
||||
const silentNeverType = createIntrinsicType(TypeFlags.Never, "never");
|
||||
const nonInferrableType = createIntrinsicType(TypeFlags.Never, "never", ObjectFlags.NonInferrableType);
|
||||
const implicitNeverType = createIntrinsicType(TypeFlags.Never, "never");
|
||||
const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object");
|
||||
const stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]);
|
||||
@@ -452,7 +453,7 @@ namespace ts {
|
||||
const anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
||||
// The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated
|
||||
// in getPropagatingFlagsOfTypes, and it is checked in inferFromTypes.
|
||||
anyFunctionType.objectFlags |= ObjectFlags.ContainsAnyFunctionType;
|
||||
anyFunctionType.objectFlags |= ObjectFlags.NonInferrableType;
|
||||
|
||||
const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
||||
const circularConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
||||
@@ -2753,14 +2754,9 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function createIntrinsicType(kind: TypeFlags, intrinsicName: string): IntrinsicType {
|
||||
function createIntrinsicType(kind: TypeFlags, intrinsicName: string, objectFlags: ObjectFlags = 0): IntrinsicType {
|
||||
const type = <IntrinsicType>createType(kind);
|
||||
type.intrinsicName = intrinsicName;
|
||||
return type;
|
||||
}
|
||||
|
||||
function createNullableType(kind: TypeFlags, intrinsicName: string, objectFlags: ObjectFlags): NullableType {
|
||||
const type = createIntrinsicType(kind, intrinsicName);
|
||||
type.objectFlags = objectFlags;
|
||||
return type;
|
||||
}
|
||||
@@ -14137,7 +14133,7 @@ namespace ts {
|
||||
const result = createAnonymousType(type.symbol, members, emptyArray, emptyArray,
|
||||
stringIndexInfo && createIndexInfo(getWidenedType(stringIndexInfo.type), stringIndexInfo.isReadonly),
|
||||
numberIndexInfo && createIndexInfo(getWidenedType(numberIndexInfo.type), numberIndexInfo.isReadonly));
|
||||
result.objectFlags |= (getObjectFlags(type) & ObjectFlags.JSLiteral); // Retain js literal flag through widening
|
||||
result.objectFlags |= (getObjectFlags(type) & (ObjectFlags.JSLiteral | ObjectFlags.NonInferrableType)); // Retain js literal flag through widening
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -14455,16 +14451,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
function createReverseMappedType(source: Type, target: MappedType, constraint: IndexType) {
|
||||
const properties = getPropertiesOfType(source);
|
||||
if (properties.length === 0 && !getIndexInfoOfType(source, IndexKind.String)) {
|
||||
return undefined;
|
||||
}
|
||||
// If any property contains context sensitive functions that have been skipped, the source type
|
||||
// is incomplete and we can't infer a meaningful input type.
|
||||
for (const prop of properties) {
|
||||
if (getObjectFlags(getTypeOfSymbol(prop)) & ObjectFlags.ContainsAnyFunctionType) {
|
||||
return undefined;
|
||||
}
|
||||
if (getObjectFlags(source) & ObjectFlags.NonInferrableType || getPropertiesOfType(source).length === 0 && !getIndexInfoOfType(source, IndexKind.String)) {
|
||||
return undefined;
|
||||
}
|
||||
// For arrays and tuples we infer new arrays and tuples where the reverse mapping has been
|
||||
// applied to the element type(s).
|
||||
@@ -14619,7 +14609,7 @@ namespace ts {
|
||||
// not contain anyFunctionType when we come back to this argument for its second round
|
||||
// of inference. Also, we exclude inferences for silentNeverType (which is used as a wildcard
|
||||
// when constructing types from type parameters that had no inference candidates).
|
||||
if (getObjectFlags(source) & ObjectFlags.ContainsAnyFunctionType || source === silentNeverType || (priority & InferencePriority.ReturnType && (source === autoType || source === autoArrayType))) {
|
||||
if (getObjectFlags(source) & ObjectFlags.NonInferrableType || source === silentNeverType || (priority & InferencePriority.ReturnType && (source === autoType || source === autoArrayType))) {
|
||||
return;
|
||||
}
|
||||
const inference = getInferenceInfoForType(target);
|
||||
@@ -14932,7 +14922,7 @@ namespace ts {
|
||||
const sourceLen = sourceSignatures.length;
|
||||
const targetLen = targetSignatures.length;
|
||||
const len = sourceLen < targetLen ? sourceLen : targetLen;
|
||||
const skipParameters = !!(getObjectFlags(source) & ObjectFlags.ContainsAnyFunctionType);
|
||||
const skipParameters = !!(getObjectFlags(source) & ObjectFlags.NonInferrableType);
|
||||
for (let i = 0; i < len; i++) {
|
||||
inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getBaseSignature(targetSignatures[targetLen - len + i]), skipParameters);
|
||||
}
|
||||
@@ -21052,7 +21042,7 @@ namespace ts {
|
||||
// returns a function type, we choose to defer processing. This narrowly permits function composition
|
||||
// operators to flow inferences through return types, but otherwise processes calls right away. We
|
||||
// use the resolvingSignature singleton to indicate that we deferred processing. This result will be
|
||||
// propagated out and eventually turned into silentNeverType (a type that is assignable to anything and
|
||||
// propagated out and eventually turned into nonInferrableType (a type that is assignable to anything and
|
||||
// from which we never make inferences).
|
||||
if (checkMode & CheckMode.SkipGenericFunctions && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) {
|
||||
skippedGenericFunction(node, checkMode);
|
||||
@@ -21535,8 +21525,8 @@ namespace ts {
|
||||
const signature = getResolvedSignature(node, /*candidatesOutArray*/ undefined, checkMode);
|
||||
if (signature === resolvingSignature) {
|
||||
// CheckMode.SkipGenericFunctions is enabled and this is a call to a generic function that
|
||||
// returns a function type. We defer checking and return anyFunctionType.
|
||||
return silentNeverType;
|
||||
// returns a function type. We defer checking and return nonInferrableType.
|
||||
return nonInferrableType;
|
||||
}
|
||||
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
@@ -22343,7 +22333,7 @@ namespace ts {
|
||||
const returnType = getReturnTypeFromBody(node, checkMode);
|
||||
const returnOnlySignature = createSignature(undefined, undefined, undefined, emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
||||
const returnOnlyType = createAnonymousType(node.symbol, emptySymbols, [returnOnlySignature], emptyArray, undefined, undefined);
|
||||
returnOnlyType.objectFlags |= ObjectFlags.ContainsAnyFunctionType;
|
||||
returnOnlyType.objectFlags |= ObjectFlags.NonInferrableType;
|
||||
return links.contextFreeType = returnOnlyType;
|
||||
}
|
||||
return anyFunctionType;
|
||||
|
||||
@@ -3944,7 +3944,7 @@ namespace ts {
|
||||
Instantiable = InstantiableNonPrimitive | InstantiablePrimitive,
|
||||
StructuredOrInstantiable = StructuredType | Instantiable,
|
||||
/* @internal */
|
||||
ObjectFlagsType = Nullable | Object | Union | Intersection,
|
||||
ObjectFlagsType = Nullable | Never | Object | Union | Intersection,
|
||||
// 'Narrowable' types are types where narrowing actually narrows.
|
||||
// This *should* be every type other than null, undefined, void, and never
|
||||
Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive,
|
||||
@@ -4064,12 +4064,12 @@ namespace ts {
|
||||
/* @internal */
|
||||
ContainsObjectLiteral = 1 << 18, // Type is or contains object literal type
|
||||
/* @internal */
|
||||
ContainsAnyFunctionType = 1 << 19, // Type is or contains the anyFunctionType
|
||||
NonInferrableType = 1 << 19, // Type is or contains anyFunctionType or silentNeverType
|
||||
ClassOrInterface = Class | Interface,
|
||||
/* @internal */
|
||||
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,
|
||||
/* @internal */
|
||||
PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | ContainsAnyFunctionType
|
||||
PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | NonInferrableType
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
||||
46
tests/baselines/reference/genericFunctionInference2.js
Normal file
46
tests/baselines/reference/genericFunctionInference2.js
Normal file
@@ -0,0 +1,46 @@
|
||||
//// [genericFunctionInference2.ts]
|
||||
// Repro from #30685
|
||||
|
||||
type Reducer<S> = (state: S) => S;
|
||||
declare function combineReducers<S>(reducers: { [K in keyof S]: Reducer<S[K]> }): Reducer<S>;
|
||||
|
||||
type MyState = { combined: { foo: number } };
|
||||
declare const foo: Reducer<MyState['combined']['foo']>;
|
||||
|
||||
const myReducer1: Reducer<MyState> = combineReducers({
|
||||
combined: combineReducers({ foo }),
|
||||
});
|
||||
|
||||
const myReducer2 = combineReducers({
|
||||
combined: combineReducers({ foo }),
|
||||
});
|
||||
|
||||
// Repro from #30942
|
||||
|
||||
declare function withH<T, U>(handlerCreators: HandleCreatorsFactory<T, U>): U;
|
||||
|
||||
type Props = { out: number }
|
||||
|
||||
type HandleCreatorsFactory<T, U> = (initialProps: T) => { [P in keyof U]: (props: T) => U[P] };
|
||||
|
||||
const enhancer4 = withH((props: Props) => ({
|
||||
onChange: (props) => (e: any) => {},
|
||||
onSubmit: (props) => (e: any) => {},
|
||||
}));
|
||||
|
||||
enhancer4.onChange(null);
|
||||
|
||||
|
||||
//// [genericFunctionInference2.js]
|
||||
// Repro from #30685
|
||||
var myReducer1 = combineReducers({
|
||||
combined: combineReducers({ foo: foo })
|
||||
});
|
||||
var myReducer2 = combineReducers({
|
||||
combined: combineReducers({ foo: foo })
|
||||
});
|
||||
var enhancer4 = withH(function (props) { return ({
|
||||
onChange: function (props) { return function (e) { }; },
|
||||
onSubmit: function (props) { return function (e) { }; }
|
||||
}); });
|
||||
enhancer4.onChange(null);
|
||||
108
tests/baselines/reference/genericFunctionInference2.symbols
Normal file
108
tests/baselines/reference/genericFunctionInference2.symbols
Normal file
@@ -0,0 +1,108 @@
|
||||
=== tests/cases/compiler/genericFunctionInference2.ts ===
|
||||
// Repro from #30685
|
||||
|
||||
type Reducer<S> = (state: S) => S;
|
||||
>Reducer : Symbol(Reducer, Decl(genericFunctionInference2.ts, 0, 0))
|
||||
>S : Symbol(S, Decl(genericFunctionInference2.ts, 2, 13))
|
||||
>state : Symbol(state, Decl(genericFunctionInference2.ts, 2, 19))
|
||||
>S : Symbol(S, Decl(genericFunctionInference2.ts, 2, 13))
|
||||
>S : Symbol(S, Decl(genericFunctionInference2.ts, 2, 13))
|
||||
|
||||
declare function combineReducers<S>(reducers: { [K in keyof S]: Reducer<S[K]> }): Reducer<S>;
|
||||
>combineReducers : Symbol(combineReducers, Decl(genericFunctionInference2.ts, 2, 34))
|
||||
>S : Symbol(S, Decl(genericFunctionInference2.ts, 3, 33))
|
||||
>reducers : Symbol(reducers, Decl(genericFunctionInference2.ts, 3, 36))
|
||||
>K : Symbol(K, Decl(genericFunctionInference2.ts, 3, 49))
|
||||
>S : Symbol(S, Decl(genericFunctionInference2.ts, 3, 33))
|
||||
>Reducer : Symbol(Reducer, Decl(genericFunctionInference2.ts, 0, 0))
|
||||
>S : Symbol(S, Decl(genericFunctionInference2.ts, 3, 33))
|
||||
>K : Symbol(K, Decl(genericFunctionInference2.ts, 3, 49))
|
||||
>Reducer : Symbol(Reducer, Decl(genericFunctionInference2.ts, 0, 0))
|
||||
>S : Symbol(S, Decl(genericFunctionInference2.ts, 3, 33))
|
||||
|
||||
type MyState = { combined: { foo: number } };
|
||||
>MyState : Symbol(MyState, Decl(genericFunctionInference2.ts, 3, 93))
|
||||
>combined : Symbol(combined, Decl(genericFunctionInference2.ts, 5, 16))
|
||||
>foo : Symbol(foo, Decl(genericFunctionInference2.ts, 5, 28))
|
||||
|
||||
declare const foo: Reducer<MyState['combined']['foo']>;
|
||||
>foo : Symbol(foo, Decl(genericFunctionInference2.ts, 6, 13))
|
||||
>Reducer : Symbol(Reducer, Decl(genericFunctionInference2.ts, 0, 0))
|
||||
>MyState : Symbol(MyState, Decl(genericFunctionInference2.ts, 3, 93))
|
||||
|
||||
const myReducer1: Reducer<MyState> = combineReducers({
|
||||
>myReducer1 : Symbol(myReducer1, Decl(genericFunctionInference2.ts, 8, 5))
|
||||
>Reducer : Symbol(Reducer, Decl(genericFunctionInference2.ts, 0, 0))
|
||||
>MyState : Symbol(MyState, Decl(genericFunctionInference2.ts, 3, 93))
|
||||
>combineReducers : Symbol(combineReducers, Decl(genericFunctionInference2.ts, 2, 34))
|
||||
|
||||
combined: combineReducers({ foo }),
|
||||
>combined : Symbol(combined, Decl(genericFunctionInference2.ts, 8, 54))
|
||||
>combineReducers : Symbol(combineReducers, Decl(genericFunctionInference2.ts, 2, 34))
|
||||
>foo : Symbol(foo, Decl(genericFunctionInference2.ts, 9, 31))
|
||||
|
||||
});
|
||||
|
||||
const myReducer2 = combineReducers({
|
||||
>myReducer2 : Symbol(myReducer2, Decl(genericFunctionInference2.ts, 12, 5))
|
||||
>combineReducers : Symbol(combineReducers, Decl(genericFunctionInference2.ts, 2, 34))
|
||||
|
||||
combined: combineReducers({ foo }),
|
||||
>combined : Symbol(combined, Decl(genericFunctionInference2.ts, 12, 36))
|
||||
>combineReducers : Symbol(combineReducers, Decl(genericFunctionInference2.ts, 2, 34))
|
||||
>foo : Symbol(foo, Decl(genericFunctionInference2.ts, 13, 31))
|
||||
|
||||
});
|
||||
|
||||
// Repro from #30942
|
||||
|
||||
declare function withH<T, U>(handlerCreators: HandleCreatorsFactory<T, U>): U;
|
||||
>withH : Symbol(withH, Decl(genericFunctionInference2.ts, 14, 3))
|
||||
>T : Symbol(T, Decl(genericFunctionInference2.ts, 18, 23))
|
||||
>U : Symbol(U, Decl(genericFunctionInference2.ts, 18, 25))
|
||||
>handlerCreators : Symbol(handlerCreators, Decl(genericFunctionInference2.ts, 18, 29))
|
||||
>HandleCreatorsFactory : Symbol(HandleCreatorsFactory, Decl(genericFunctionInference2.ts, 20, 28))
|
||||
>T : Symbol(T, Decl(genericFunctionInference2.ts, 18, 23))
|
||||
>U : Symbol(U, Decl(genericFunctionInference2.ts, 18, 25))
|
||||
>U : Symbol(U, Decl(genericFunctionInference2.ts, 18, 25))
|
||||
|
||||
type Props = { out: number }
|
||||
>Props : Symbol(Props, Decl(genericFunctionInference2.ts, 18, 78))
|
||||
>out : Symbol(out, Decl(genericFunctionInference2.ts, 20, 14))
|
||||
|
||||
type HandleCreatorsFactory<T, U> = (initialProps: T) => { [P in keyof U]: (props: T) => U[P] };
|
||||
>HandleCreatorsFactory : Symbol(HandleCreatorsFactory, Decl(genericFunctionInference2.ts, 20, 28))
|
||||
>T : Symbol(T, Decl(genericFunctionInference2.ts, 22, 27))
|
||||
>U : Symbol(U, Decl(genericFunctionInference2.ts, 22, 29))
|
||||
>initialProps : Symbol(initialProps, Decl(genericFunctionInference2.ts, 22, 36))
|
||||
>T : Symbol(T, Decl(genericFunctionInference2.ts, 22, 27))
|
||||
>P : Symbol(P, Decl(genericFunctionInference2.ts, 22, 59))
|
||||
>U : Symbol(U, Decl(genericFunctionInference2.ts, 22, 29))
|
||||
>props : Symbol(props, Decl(genericFunctionInference2.ts, 22, 75))
|
||||
>T : Symbol(T, Decl(genericFunctionInference2.ts, 22, 27))
|
||||
>U : Symbol(U, Decl(genericFunctionInference2.ts, 22, 29))
|
||||
>P : Symbol(P, Decl(genericFunctionInference2.ts, 22, 59))
|
||||
|
||||
const enhancer4 = withH((props: Props) => ({
|
||||
>enhancer4 : Symbol(enhancer4, Decl(genericFunctionInference2.ts, 24, 5))
|
||||
>withH : Symbol(withH, Decl(genericFunctionInference2.ts, 14, 3))
|
||||
>props : Symbol(props, Decl(genericFunctionInference2.ts, 24, 25))
|
||||
>Props : Symbol(Props, Decl(genericFunctionInference2.ts, 18, 78))
|
||||
|
||||
onChange: (props) => (e: any) => {},
|
||||
>onChange : Symbol(onChange, Decl(genericFunctionInference2.ts, 24, 44))
|
||||
>props : Symbol(props, Decl(genericFunctionInference2.ts, 25, 15))
|
||||
>e : Symbol(e, Decl(genericFunctionInference2.ts, 25, 26))
|
||||
|
||||
onSubmit: (props) => (e: any) => {},
|
||||
>onSubmit : Symbol(onSubmit, Decl(genericFunctionInference2.ts, 25, 40))
|
||||
>props : Symbol(props, Decl(genericFunctionInference2.ts, 26, 15))
|
||||
>e : Symbol(e, Decl(genericFunctionInference2.ts, 26, 26))
|
||||
|
||||
}));
|
||||
|
||||
enhancer4.onChange(null);
|
||||
>enhancer4.onChange : Symbol(onChange, Decl(genericFunctionInference2.ts, 24, 44))
|
||||
>enhancer4 : Symbol(enhancer4, Decl(genericFunctionInference2.ts, 24, 5))
|
||||
>onChange : Symbol(onChange, Decl(genericFunctionInference2.ts, 24, 44))
|
||||
|
||||
96
tests/baselines/reference/genericFunctionInference2.types
Normal file
96
tests/baselines/reference/genericFunctionInference2.types
Normal file
@@ -0,0 +1,96 @@
|
||||
=== tests/cases/compiler/genericFunctionInference2.ts ===
|
||||
// Repro from #30685
|
||||
|
||||
type Reducer<S> = (state: S) => S;
|
||||
>Reducer : Reducer<S>
|
||||
>state : S
|
||||
|
||||
declare function combineReducers<S>(reducers: { [K in keyof S]: Reducer<S[K]> }): Reducer<S>;
|
||||
>combineReducers : <S>(reducers: { [K in keyof S]: Reducer<S[K]>; }) => Reducer<S>
|
||||
>reducers : { [K in keyof S]: Reducer<S[K]>; }
|
||||
|
||||
type MyState = { combined: { foo: number } };
|
||||
>MyState : MyState
|
||||
>combined : { foo: number; }
|
||||
>foo : number
|
||||
|
||||
declare const foo: Reducer<MyState['combined']['foo']>;
|
||||
>foo : Reducer<number>
|
||||
|
||||
const myReducer1: Reducer<MyState> = combineReducers({
|
||||
>myReducer1 : Reducer<MyState>
|
||||
>combineReducers({ combined: combineReducers({ foo }),}) : Reducer<{ combined: { foo: any; }; }>
|
||||
>combineReducers : <S>(reducers: { [K in keyof S]: Reducer<S[K]>; }) => Reducer<S>
|
||||
>{ combined: combineReducers({ foo }),} : { combined: Reducer<{ foo: number; }>; }
|
||||
|
||||
combined: combineReducers({ foo }),
|
||||
>combined : Reducer<{ foo: number; }>
|
||||
>combineReducers({ foo }) : Reducer<{ foo: number; }>
|
||||
>combineReducers : <S>(reducers: { [K in keyof S]: Reducer<S[K]>; }) => Reducer<S>
|
||||
>{ foo } : { foo: Reducer<number>; }
|
||||
>foo : Reducer<number>
|
||||
|
||||
});
|
||||
|
||||
const myReducer2 = combineReducers({
|
||||
>myReducer2 : Reducer<{ combined: { foo: any; }; }>
|
||||
>combineReducers({ combined: combineReducers({ foo }),}) : Reducer<{ combined: { foo: any; }; }>
|
||||
>combineReducers : <S>(reducers: { [K in keyof S]: Reducer<S[K]>; }) => Reducer<S>
|
||||
>{ combined: combineReducers({ foo }),} : { combined: Reducer<{ foo: number; }>; }
|
||||
|
||||
combined: combineReducers({ foo }),
|
||||
>combined : Reducer<{ foo: number; }>
|
||||
>combineReducers({ foo }) : Reducer<{ foo: number; }>
|
||||
>combineReducers : <S>(reducers: { [K in keyof S]: Reducer<S[K]>; }) => Reducer<S>
|
||||
>{ foo } : { foo: Reducer<number>; }
|
||||
>foo : Reducer<number>
|
||||
|
||||
});
|
||||
|
||||
// Repro from #30942
|
||||
|
||||
declare function withH<T, U>(handlerCreators: HandleCreatorsFactory<T, U>): U;
|
||||
>withH : <T, U>(handlerCreators: HandleCreatorsFactory<T, U>) => U
|
||||
>handlerCreators : HandleCreatorsFactory<T, U>
|
||||
|
||||
type Props = { out: number }
|
||||
>Props : Props
|
||||
>out : number
|
||||
|
||||
type HandleCreatorsFactory<T, U> = (initialProps: T) => { [P in keyof U]: (props: T) => U[P] };
|
||||
>HandleCreatorsFactory : HandleCreatorsFactory<T, U>
|
||||
>initialProps : T
|
||||
>props : T
|
||||
|
||||
const enhancer4 = withH((props: Props) => ({
|
||||
>enhancer4 : { onChange: (e: any) => void; onSubmit: (e: any) => void; }
|
||||
>withH((props: Props) => ({ onChange: (props) => (e: any) => {}, onSubmit: (props) => (e: any) => {},})) : { onChange: (e: any) => void; onSubmit: (e: any) => void; }
|
||||
>withH : <T, U>(handlerCreators: HandleCreatorsFactory<T, U>) => U
|
||||
>(props: Props) => ({ onChange: (props) => (e: any) => {}, onSubmit: (props) => (e: any) => {},}) : (props: Props) => { onChange: (props: Props) => (e: any) => void; onSubmit: (props: Props) => (e: any) => void; }
|
||||
>props : Props
|
||||
>({ onChange: (props) => (e: any) => {}, onSubmit: (props) => (e: any) => {},}) : { onChange: (props: Props) => (e: any) => void; onSubmit: (props: Props) => (e: any) => void; }
|
||||
>{ onChange: (props) => (e: any) => {}, onSubmit: (props) => (e: any) => {},} : { onChange: (props: Props) => (e: any) => void; onSubmit: (props: Props) => (e: any) => void; }
|
||||
|
||||
onChange: (props) => (e: any) => {},
|
||||
>onChange : (props: Props) => (e: any) => void
|
||||
>(props) => (e: any) => {} : (props: Props) => (e: any) => void
|
||||
>props : Props
|
||||
>(e: any) => {} : (e: any) => void
|
||||
>e : any
|
||||
|
||||
onSubmit: (props) => (e: any) => {},
|
||||
>onSubmit : (props: Props) => (e: any) => void
|
||||
>(props) => (e: any) => {} : (props: Props) => (e: any) => void
|
||||
>props : Props
|
||||
>(e: any) => {} : (e: any) => void
|
||||
>e : any
|
||||
|
||||
}));
|
||||
|
||||
enhancer4.onChange(null);
|
||||
>enhancer4.onChange(null) : void
|
||||
>enhancer4.onChange : (e: any) => void
|
||||
>enhancer4 : { onChange: (e: any) => void; onSubmit: (e: any) => void; }
|
||||
>onChange : (e: any) => void
|
||||
>null : null
|
||||
|
||||
30
tests/cases/compiler/genericFunctionInference2.ts
Normal file
30
tests/cases/compiler/genericFunctionInference2.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
// Repro from #30685
|
||||
|
||||
type Reducer<S> = (state: S) => S;
|
||||
declare function combineReducers<S>(reducers: { [K in keyof S]: Reducer<S[K]> }): Reducer<S>;
|
||||
|
||||
type MyState = { combined: { foo: number } };
|
||||
declare const foo: Reducer<MyState['combined']['foo']>;
|
||||
|
||||
const myReducer1: Reducer<MyState> = combineReducers({
|
||||
combined: combineReducers({ foo }),
|
||||
});
|
||||
|
||||
const myReducer2 = combineReducers({
|
||||
combined: combineReducers({ foo }),
|
||||
});
|
||||
|
||||
// Repro from #30942
|
||||
|
||||
declare function withH<T, U>(handlerCreators: HandleCreatorsFactory<T, U>): U;
|
||||
|
||||
type Props = { out: number }
|
||||
|
||||
type HandleCreatorsFactory<T, U> = (initialProps: T) => { [P in keyof U]: (props: T) => U[P] };
|
||||
|
||||
const enhancer4 = withH((props: Props) => ({
|
||||
onChange: (props) => (e: any) => {},
|
||||
onSubmit: (props) => (e: any) => {},
|
||||
}));
|
||||
|
||||
enhancer4.onChange(null);
|
||||
Reference in New Issue
Block a user