mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Allow non-generic return types to be read from single generic call signatures (#54477)
Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
This commit is contained in:
parent
0e610182d8
commit
afffad43f4
@ -38870,17 +38870,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
}
|
||||
|
||||
function getReturnTypeOfSingleNonGenericCallSignature(funcType: Type) {
|
||||
function getNonGenericReturnTypeOfSingleCallSignature(funcType: Type) {
|
||||
const signature = getSingleCallSignature(funcType);
|
||||
if (signature && !signature.typeParameters) {
|
||||
return getReturnTypeOfSignature(signature);
|
||||
if (signature) {
|
||||
const returnType = getReturnTypeOfSignature(signature);
|
||||
if (!signature.typeParameters || !couldContainTypeVariables(returnType)) {
|
||||
return returnType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getReturnTypeOfSingleNonGenericSignatureOfCallChain(expr: CallChain) {
|
||||
const funcType = checkExpression(expr.expression);
|
||||
const nonOptionalType = getOptionalExpressionType(funcType, expr.expression);
|
||||
const returnType = getReturnTypeOfSingleNonGenericCallSignature(funcType);
|
||||
const returnType = getNonGenericReturnTypeOfSingleCallSignature(funcType);
|
||||
return returnType && propagateOptionalTypeMarker(returnType, expr, nonOptionalType !== funcType);
|
||||
}
|
||||
|
||||
@ -38929,7 +38932,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// signature where we can just fetch the return type without checking the arguments.
|
||||
if (isCallExpression(expr) && expr.expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*requireStringLiteralLikeArgument*/ true) && !isSymbolOrSymbolForCall(expr)) {
|
||||
return isCallChain(expr) ? getReturnTypeOfSingleNonGenericSignatureOfCallChain(expr) :
|
||||
getReturnTypeOfSingleNonGenericCallSignature(checkNonNullExpression(expr.expression));
|
||||
getNonGenericReturnTypeOfSingleCallSignature(checkNonNullExpression(expr.expression));
|
||||
}
|
||||
else if (isAssertionExpression(expr) && !isConstTypeReference(expr.type)) {
|
||||
return getTypeFromTypeNode((expr as TypeAssertion).type);
|
||||
|
||||
@ -31,7 +31,7 @@ const inputALike: ArrayLike<A> = { length: 0 };
|
||||
const inputARand = getEither(inputA, inputALike);
|
||||
>inputARand : ArrayLike<A> | Iterable<A>
|
||||
>getEither(inputA, inputALike) : ArrayLike<A> | Iterable<A>
|
||||
>getEither : <T>(in1: Iterable<T>, in2: ArrayLike<T>) => ArrayLike<T> | Iterable<T>
|
||||
>getEither : <T>(in1: Iterable<T>, in2: ArrayLike<T>) => Iterable<T> | ArrayLike<T>
|
||||
>inputA : A[]
|
||||
>inputALike : ArrayLike<A>
|
||||
|
||||
@ -163,12 +163,12 @@ const result11: B[] = Array.from(inputASet, ({ a }): B => ({ b: a }));
|
||||
// the ?: as always taking the false branch, narrowing to ArrayLike<T>,
|
||||
// even when the type is written as : Iterable<T>|ArrayLike<T>
|
||||
function getEither<T> (in1: Iterable<T>, in2: ArrayLike<T>) {
|
||||
>getEither : <T>(in1: Iterable<T>, in2: ArrayLike<T>) => ArrayLike<T> | Iterable<T>
|
||||
>getEither : <T>(in1: Iterable<T>, in2: ArrayLike<T>) => Iterable<T> | ArrayLike<T>
|
||||
>in1 : Iterable<T>
|
||||
>in2 : ArrayLike<T>
|
||||
|
||||
return Math.random() > 0.5 ? in1 : in2;
|
||||
>Math.random() > 0.5 ? in1 : in2 : ArrayLike<T> | Iterable<T>
|
||||
>Math.random() > 0.5 ? in1 : in2 : Iterable<T> | ArrayLike<T>
|
||||
>Math.random() > 0.5 : boolean
|
||||
>Math.random() : number
|
||||
>Math.random : () => number
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
//// [tests/cases/compiler/circularReferenceInReturnType.ts] ////
|
||||
|
||||
=== circularReferenceInReturnType.ts ===
|
||||
declare function fn1<T>(cb: () => T): string;
|
||||
>fn1 : Symbol(fn1, Decl(circularReferenceInReturnType.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(circularReferenceInReturnType.ts, 0, 21))
|
||||
>cb : Symbol(cb, Decl(circularReferenceInReturnType.ts, 0, 24))
|
||||
>T : Symbol(T, Decl(circularReferenceInReturnType.ts, 0, 21))
|
||||
|
||||
const res1 = fn1(() => res1);
|
||||
>res1 : Symbol(res1, Decl(circularReferenceInReturnType.ts, 1, 5))
|
||||
>fn1 : Symbol(fn1, Decl(circularReferenceInReturnType.ts, 0, 0))
|
||||
>res1 : Symbol(res1, Decl(circularReferenceInReturnType.ts, 1, 5))
|
||||
|
||||
declare function fn2<T>(): (cb: () => any) => (a: T) => void;
|
||||
>fn2 : Symbol(fn2, Decl(circularReferenceInReturnType.ts, 1, 29))
|
||||
>T : Symbol(T, Decl(circularReferenceInReturnType.ts, 3, 21))
|
||||
>cb : Symbol(cb, Decl(circularReferenceInReturnType.ts, 3, 28))
|
||||
>a : Symbol(a, Decl(circularReferenceInReturnType.ts, 3, 47))
|
||||
>T : Symbol(T, Decl(circularReferenceInReturnType.ts, 3, 21))
|
||||
|
||||
const res2 = fn2()(() => res2);
|
||||
>res2 : Symbol(res2, Decl(circularReferenceInReturnType.ts, 4, 5))
|
||||
>fn2 : Symbol(fn2, Decl(circularReferenceInReturnType.ts, 1, 29))
|
||||
>res2 : Symbol(res2, Decl(circularReferenceInReturnType.ts, 4, 5))
|
||||
|
||||
declare function fn3<T>(): <T2>(cb: (arg: T2) => any) => (a: T) => void;
|
||||
>fn3 : Symbol(fn3, Decl(circularReferenceInReturnType.ts, 4, 31))
|
||||
>T : Symbol(T, Decl(circularReferenceInReturnType.ts, 6, 21))
|
||||
>T2 : Symbol(T2, Decl(circularReferenceInReturnType.ts, 6, 28))
|
||||
>cb : Symbol(cb, Decl(circularReferenceInReturnType.ts, 6, 32))
|
||||
>arg : Symbol(arg, Decl(circularReferenceInReturnType.ts, 6, 37))
|
||||
>T2 : Symbol(T2, Decl(circularReferenceInReturnType.ts, 6, 28))
|
||||
>a : Symbol(a, Decl(circularReferenceInReturnType.ts, 6, 58))
|
||||
>T : Symbol(T, Decl(circularReferenceInReturnType.ts, 6, 21))
|
||||
|
||||
const res3 = fn3()(() => res3);
|
||||
>res3 : Symbol(res3, Decl(circularReferenceInReturnType.ts, 7, 5))
|
||||
>fn3 : Symbol(fn3, Decl(circularReferenceInReturnType.ts, 4, 31))
|
||||
>res3 : Symbol(res3, Decl(circularReferenceInReturnType.ts, 7, 5))
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
//// [tests/cases/compiler/circularReferenceInReturnType.ts] ////
|
||||
|
||||
=== circularReferenceInReturnType.ts ===
|
||||
declare function fn1<T>(cb: () => T): string;
|
||||
>fn1 : <T>(cb: () => T) => string
|
||||
>cb : () => T
|
||||
|
||||
const res1 = fn1(() => res1);
|
||||
>res1 : string
|
||||
>fn1(() => res1) : string
|
||||
>fn1 : <T>(cb: () => T) => string
|
||||
>() => res1 : () => string
|
||||
>res1 : string
|
||||
|
||||
declare function fn2<T>(): (cb: () => any) => (a: T) => void;
|
||||
>fn2 : <T>() => (cb: () => any) => (a: T) => void
|
||||
>cb : () => any
|
||||
>a : T
|
||||
|
||||
const res2 = fn2()(() => res2);
|
||||
>res2 : (a: unknown) => void
|
||||
>fn2()(() => res2) : (a: unknown) => void
|
||||
>fn2() : (cb: () => any) => (a: unknown) => void
|
||||
>fn2 : <T>() => (cb: () => any) => (a: T) => void
|
||||
>() => res2 : () => (a: unknown) => void
|
||||
>res2 : (a: unknown) => void
|
||||
|
||||
declare function fn3<T>(): <T2>(cb: (arg: T2) => any) => (a: T) => void;
|
||||
>fn3 : <T>() => <T2>(cb: (arg: T2) => any) => (a: T) => void
|
||||
>cb : (arg: T2) => any
|
||||
>arg : T2
|
||||
>a : T
|
||||
|
||||
const res3 = fn3()(() => res3);
|
||||
>res3 : (a: unknown) => void
|
||||
>fn3()(() => res3) : (a: unknown) => void
|
||||
>fn3() : <T2>(cb: (arg: T2) => any) => (a: unknown) => void
|
||||
>fn3 : <T>() => <T2>(cb: (arg: T2) => any) => (a: T) => void
|
||||
>() => res3 : () => (a: unknown) => void
|
||||
>res3 : (a: unknown) => void
|
||||
|
||||
160
tests/baselines/reference/circularReferenceInReturnType2.symbols
Normal file
160
tests/baselines/reference/circularReferenceInReturnType2.symbols
Normal file
@ -0,0 +1,160 @@
|
||||
//// [tests/cases/compiler/circularReferenceInReturnType2.ts] ////
|
||||
|
||||
=== circularReferenceInReturnType2.ts ===
|
||||
type ObjectType<Source> = {
|
||||
>ObjectType : Symbol(ObjectType, Decl(circularReferenceInReturnType2.ts, 0, 0))
|
||||
>Source : Symbol(Source, Decl(circularReferenceInReturnType2.ts, 0, 16))
|
||||
|
||||
kind: "object";
|
||||
>kind : Symbol(kind, Decl(circularReferenceInReturnType2.ts, 0, 27))
|
||||
|
||||
__source: (source: Source) => void;
|
||||
>__source : Symbol(__source, Decl(circularReferenceInReturnType2.ts, 1, 17))
|
||||
>source : Symbol(source, Decl(circularReferenceInReturnType2.ts, 2, 13))
|
||||
>Source : Symbol(Source, Decl(circularReferenceInReturnType2.ts, 0, 16))
|
||||
|
||||
};
|
||||
|
||||
type Field<Source, Key extends string> = {
|
||||
>Field : Symbol(Field, Decl(circularReferenceInReturnType2.ts, 3, 2))
|
||||
>Source : Symbol(Source, Decl(circularReferenceInReturnType2.ts, 5, 11))
|
||||
>Key : Symbol(Key, Decl(circularReferenceInReturnType2.ts, 5, 18))
|
||||
|
||||
__key: (key: Key) => void;
|
||||
>__key : Symbol(__key, Decl(circularReferenceInReturnType2.ts, 5, 42))
|
||||
>key : Symbol(key, Decl(circularReferenceInReturnType2.ts, 6, 10))
|
||||
>Key : Symbol(Key, Decl(circularReferenceInReturnType2.ts, 5, 18))
|
||||
|
||||
__source: (source: Source) => void;
|
||||
>__source : Symbol(__source, Decl(circularReferenceInReturnType2.ts, 6, 28))
|
||||
>source : Symbol(source, Decl(circularReferenceInReturnType2.ts, 7, 13))
|
||||
>Source : Symbol(Source, Decl(circularReferenceInReturnType2.ts, 5, 11))
|
||||
|
||||
};
|
||||
|
||||
declare const object: <Source>() => <
|
||||
>object : Symbol(object, Decl(circularReferenceInReturnType2.ts, 10, 13))
|
||||
>Source : Symbol(Source, Decl(circularReferenceInReturnType2.ts, 10, 23))
|
||||
|
||||
Fields extends {
|
||||
>Fields : Symbol(Fields, Decl(circularReferenceInReturnType2.ts, 10, 37))
|
||||
|
||||
[Key in keyof Fields]: Field<Source, Key & string>;
|
||||
>Key : Symbol(Key, Decl(circularReferenceInReturnType2.ts, 12, 5))
|
||||
>Fields : Symbol(Fields, Decl(circularReferenceInReturnType2.ts, 10, 37))
|
||||
>Field : Symbol(Field, Decl(circularReferenceInReturnType2.ts, 3, 2))
|
||||
>Source : Symbol(Source, Decl(circularReferenceInReturnType2.ts, 10, 23))
|
||||
>Key : Symbol(Key, Decl(circularReferenceInReturnType2.ts, 12, 5))
|
||||
}
|
||||
>(config: {
|
||||
>config : Symbol(config, Decl(circularReferenceInReturnType2.ts, 14, 2))
|
||||
|
||||
name: string;
|
||||
>name : Symbol(name, Decl(circularReferenceInReturnType2.ts, 14, 11))
|
||||
|
||||
fields: Fields | (() => Fields);
|
||||
>fields : Symbol(fields, Decl(circularReferenceInReturnType2.ts, 15, 15))
|
||||
>Fields : Symbol(Fields, Decl(circularReferenceInReturnType2.ts, 10, 37))
|
||||
>Fields : Symbol(Fields, Decl(circularReferenceInReturnType2.ts, 10, 37))
|
||||
|
||||
}) => ObjectType<Source>;
|
||||
>ObjectType : Symbol(ObjectType, Decl(circularReferenceInReturnType2.ts, 0, 0))
|
||||
>Source : Symbol(Source, Decl(circularReferenceInReturnType2.ts, 10, 23))
|
||||
|
||||
type InferValueFromObjectType<Type extends ObjectType<any>> =
|
||||
>InferValueFromObjectType : Symbol(InferValueFromObjectType, Decl(circularReferenceInReturnType2.ts, 17, 25))
|
||||
>Type : Symbol(Type, Decl(circularReferenceInReturnType2.ts, 19, 30))
|
||||
>ObjectType : Symbol(ObjectType, Decl(circularReferenceInReturnType2.ts, 0, 0))
|
||||
|
||||
Type extends ObjectType<infer Source> ? Source : never;
|
||||
>Type : Symbol(Type, Decl(circularReferenceInReturnType2.ts, 19, 30))
|
||||
>ObjectType : Symbol(ObjectType, Decl(circularReferenceInReturnType2.ts, 0, 0))
|
||||
>Source : Symbol(Source, Decl(circularReferenceInReturnType2.ts, 20, 31))
|
||||
>Source : Symbol(Source, Decl(circularReferenceInReturnType2.ts, 20, 31))
|
||||
|
||||
type FieldResolver<Source, TType extends ObjectType<any>> = (
|
||||
>FieldResolver : Symbol(FieldResolver, Decl(circularReferenceInReturnType2.ts, 20, 57))
|
||||
>Source : Symbol(Source, Decl(circularReferenceInReturnType2.ts, 22, 19))
|
||||
>TType : Symbol(TType, Decl(circularReferenceInReturnType2.ts, 22, 26))
|
||||
>ObjectType : Symbol(ObjectType, Decl(circularReferenceInReturnType2.ts, 0, 0))
|
||||
|
||||
source: Source
|
||||
>source : Symbol(source, Decl(circularReferenceInReturnType2.ts, 22, 61))
|
||||
>Source : Symbol(Source, Decl(circularReferenceInReturnType2.ts, 22, 19))
|
||||
|
||||
) => InferValueFromObjectType<TType>;
|
||||
>InferValueFromObjectType : Symbol(InferValueFromObjectType, Decl(circularReferenceInReturnType2.ts, 17, 25))
|
||||
>TType : Symbol(TType, Decl(circularReferenceInReturnType2.ts, 22, 26))
|
||||
|
||||
type FieldFuncArgs<Source, Type extends ObjectType<any>> = {
|
||||
>FieldFuncArgs : Symbol(FieldFuncArgs, Decl(circularReferenceInReturnType2.ts, 24, 37))
|
||||
>Source : Symbol(Source, Decl(circularReferenceInReturnType2.ts, 26, 19))
|
||||
>Type : Symbol(Type, Decl(circularReferenceInReturnType2.ts, 26, 26))
|
||||
>ObjectType : Symbol(ObjectType, Decl(circularReferenceInReturnType2.ts, 0, 0))
|
||||
|
||||
type: Type;
|
||||
>type : Symbol(type, Decl(circularReferenceInReturnType2.ts, 26, 60))
|
||||
>Type : Symbol(Type, Decl(circularReferenceInReturnType2.ts, 26, 26))
|
||||
|
||||
resolve: FieldResolver<Source, Type>;
|
||||
>resolve : Symbol(resolve, Decl(circularReferenceInReturnType2.ts, 27, 13))
|
||||
>FieldResolver : Symbol(FieldResolver, Decl(circularReferenceInReturnType2.ts, 20, 57))
|
||||
>Source : Symbol(Source, Decl(circularReferenceInReturnType2.ts, 26, 19))
|
||||
>Type : Symbol(Type, Decl(circularReferenceInReturnType2.ts, 26, 26))
|
||||
|
||||
};
|
||||
|
||||
declare const field: <Source, Type extends ObjectType<any>, Key extends string>(
|
||||
>field : Symbol(field, Decl(circularReferenceInReturnType2.ts, 31, 13))
|
||||
>Source : Symbol(Source, Decl(circularReferenceInReturnType2.ts, 31, 22))
|
||||
>Type : Symbol(Type, Decl(circularReferenceInReturnType2.ts, 31, 29))
|
||||
>ObjectType : Symbol(ObjectType, Decl(circularReferenceInReturnType2.ts, 0, 0))
|
||||
>Key : Symbol(Key, Decl(circularReferenceInReturnType2.ts, 31, 59))
|
||||
|
||||
field: FieldFuncArgs<Source, Type>
|
||||
>field : Symbol(field, Decl(circularReferenceInReturnType2.ts, 31, 80))
|
||||
>FieldFuncArgs : Symbol(FieldFuncArgs, Decl(circularReferenceInReturnType2.ts, 24, 37))
|
||||
>Source : Symbol(Source, Decl(circularReferenceInReturnType2.ts, 31, 22))
|
||||
>Type : Symbol(Type, Decl(circularReferenceInReturnType2.ts, 31, 29))
|
||||
|
||||
) => Field<Source, Key>;
|
||||
>Field : Symbol(Field, Decl(circularReferenceInReturnType2.ts, 3, 2))
|
||||
>Source : Symbol(Source, Decl(circularReferenceInReturnType2.ts, 31, 22))
|
||||
>Key : Symbol(Key, Decl(circularReferenceInReturnType2.ts, 31, 59))
|
||||
|
||||
type Something = { foo: number };
|
||||
>Something : Symbol(Something, Decl(circularReferenceInReturnType2.ts, 33, 24))
|
||||
>foo : Symbol(foo, Decl(circularReferenceInReturnType2.ts, 35, 18))
|
||||
|
||||
const A = object<Something>()({
|
||||
>A : Symbol(A, Decl(circularReferenceInReturnType2.ts, 37, 5))
|
||||
>object : Symbol(object, Decl(circularReferenceInReturnType2.ts, 10, 13))
|
||||
>Something : Symbol(Something, Decl(circularReferenceInReturnType2.ts, 33, 24))
|
||||
|
||||
name: "A",
|
||||
>name : Symbol(name, Decl(circularReferenceInReturnType2.ts, 37, 31))
|
||||
|
||||
fields: () => ({
|
||||
>fields : Symbol(fields, Decl(circularReferenceInReturnType2.ts, 38, 12))
|
||||
|
||||
a: field({
|
||||
>a : Symbol(a, Decl(circularReferenceInReturnType2.ts, 39, 18))
|
||||
>field : Symbol(field, Decl(circularReferenceInReturnType2.ts, 31, 13))
|
||||
|
||||
type: A,
|
||||
>type : Symbol(type, Decl(circularReferenceInReturnType2.ts, 40, 14))
|
||||
>A : Symbol(A, Decl(circularReferenceInReturnType2.ts, 37, 5))
|
||||
|
||||
resolve() {
|
||||
>resolve : Symbol(resolve, Decl(circularReferenceInReturnType2.ts, 41, 14))
|
||||
|
||||
return {
|
||||
foo: 100,
|
||||
>foo : Symbol(foo, Decl(circularReferenceInReturnType2.ts, 43, 16))
|
||||
|
||||
};
|
||||
},
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
124
tests/baselines/reference/circularReferenceInReturnType2.types
Normal file
124
tests/baselines/reference/circularReferenceInReturnType2.types
Normal file
@ -0,0 +1,124 @@
|
||||
//// [tests/cases/compiler/circularReferenceInReturnType2.ts] ////
|
||||
|
||||
=== circularReferenceInReturnType2.ts ===
|
||||
type ObjectType<Source> = {
|
||||
>ObjectType : ObjectType<Source>
|
||||
|
||||
kind: "object";
|
||||
>kind : "object"
|
||||
|
||||
__source: (source: Source) => void;
|
||||
>__source : (source: Source) => void
|
||||
>source : Source
|
||||
|
||||
};
|
||||
|
||||
type Field<Source, Key extends string> = {
|
||||
>Field : Field<Source, Key>
|
||||
|
||||
__key: (key: Key) => void;
|
||||
>__key : (key: Key) => void
|
||||
>key : Key
|
||||
|
||||
__source: (source: Source) => void;
|
||||
>__source : (source: Source) => void
|
||||
>source : Source
|
||||
|
||||
};
|
||||
|
||||
declare const object: <Source>() => <
|
||||
>object : <Source>() => <Fields extends { [Key in keyof Fields]: Field<Source, Key & string>; }>(config: { name: string; fields: Fields | (() => Fields);}) => ObjectType<Source>
|
||||
|
||||
Fields extends {
|
||||
[Key in keyof Fields]: Field<Source, Key & string>;
|
||||
}
|
||||
>(config: {
|
||||
>config : { name: string; fields: Fields | (() => Fields); }
|
||||
|
||||
name: string;
|
||||
>name : string
|
||||
|
||||
fields: Fields | (() => Fields);
|
||||
>fields : Fields | (() => Fields)
|
||||
|
||||
}) => ObjectType<Source>;
|
||||
|
||||
type InferValueFromObjectType<Type extends ObjectType<any>> =
|
||||
>InferValueFromObjectType : InferValueFromObjectType<Type>
|
||||
|
||||
Type extends ObjectType<infer Source> ? Source : never;
|
||||
|
||||
type FieldResolver<Source, TType extends ObjectType<any>> = (
|
||||
>FieldResolver : FieldResolver<Source, TType>
|
||||
|
||||
source: Source
|
||||
>source : Source
|
||||
|
||||
) => InferValueFromObjectType<TType>;
|
||||
|
||||
type FieldFuncArgs<Source, Type extends ObjectType<any>> = {
|
||||
>FieldFuncArgs : FieldFuncArgs<Source, Type>
|
||||
|
||||
type: Type;
|
||||
>type : Type
|
||||
|
||||
resolve: FieldResolver<Source, Type>;
|
||||
>resolve : FieldResolver<Source, Type>
|
||||
|
||||
};
|
||||
|
||||
declare const field: <Source, Type extends ObjectType<any>, Key extends string>(
|
||||
>field : <Source, Type extends ObjectType<any>, Key extends string>(field: FieldFuncArgs<Source, Type>) => Field<Source, Key>
|
||||
|
||||
field: FieldFuncArgs<Source, Type>
|
||||
>field : FieldFuncArgs<Source, Type>
|
||||
|
||||
) => Field<Source, Key>;
|
||||
|
||||
type Something = { foo: number };
|
||||
>Something : { foo: number; }
|
||||
>foo : number
|
||||
|
||||
const A = object<Something>()({
|
||||
>A : ObjectType<Something>
|
||||
>object<Something>()({ name: "A", fields: () => ({ a: field({ type: A, resolve() { return { foo: 100, }; }, }), }),}) : ObjectType<Something>
|
||||
>object<Something>() : <Fields extends { [Key in keyof Fields]: Field<Something, Key & string>; }>(config: { name: string; fields: Fields | (() => Fields); }) => ObjectType<Something>
|
||||
>object : <Source>() => <Fields extends { [Key in keyof Fields]: Field<Source, Key & string>; }>(config: { name: string; fields: Fields | (() => Fields); }) => ObjectType<Source>
|
||||
>{ name: "A", fields: () => ({ a: field({ type: A, resolve() { return { foo: 100, }; }, }), }),} : { name: string; fields: () => { a: Field<Something, "a">; }; }
|
||||
|
||||
name: "A",
|
||||
>name : string
|
||||
>"A" : "A"
|
||||
|
||||
fields: () => ({
|
||||
>fields : () => { a: Field<Something, "a">; }
|
||||
>() => ({ a: field({ type: A, resolve() { return { foo: 100, }; }, }), }) : () => { a: Field<Something, "a">; }
|
||||
>({ a: field({ type: A, resolve() { return { foo: 100, }; }, }), }) : { a: Field<Something, "a">; }
|
||||
>{ a: field({ type: A, resolve() { return { foo: 100, }; }, }), } : { a: Field<Something, "a">; }
|
||||
|
||||
a: field({
|
||||
>a : Field<Something, "a">
|
||||
>field({ type: A, resolve() { return { foo: 100, }; }, }) : Field<Something, "a">
|
||||
>field : <Source, Type extends ObjectType<any>, Key extends string>(field: FieldFuncArgs<Source, Type>) => Field<Source, Key>
|
||||
>{ type: A, resolve() { return { foo: 100, }; }, } : { type: ObjectType<Something>; resolve(): { foo: number; }; }
|
||||
|
||||
type: A,
|
||||
>type : ObjectType<Something>
|
||||
>A : ObjectType<Something>
|
||||
|
||||
resolve() {
|
||||
>resolve : () => { foo: number; }
|
||||
|
||||
return {
|
||||
>{ foo: 100, } : { foo: number; }
|
||||
|
||||
foo: 100,
|
||||
>foo : number
|
||||
>100 : 100
|
||||
|
||||
};
|
||||
},
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
11
tests/cases/compiler/circularReferenceInReturnType.ts
Normal file
11
tests/cases/compiler/circularReferenceInReturnType.ts
Normal file
@ -0,0 +1,11 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
declare function fn1<T>(cb: () => T): string;
|
||||
const res1 = fn1(() => res1);
|
||||
|
||||
declare function fn2<T>(): (cb: () => any) => (a: T) => void;
|
||||
const res2 = fn2()(() => res2);
|
||||
|
||||
declare function fn3<T>(): <T2>(cb: (arg: T2) => any) => (a: T) => void;
|
||||
const res3 = fn3()(() => res3);
|
||||
53
tests/cases/compiler/circularReferenceInReturnType2.ts
Normal file
53
tests/cases/compiler/circularReferenceInReturnType2.ts
Normal file
@ -0,0 +1,53 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
type ObjectType<Source> = {
|
||||
kind: "object";
|
||||
__source: (source: Source) => void;
|
||||
};
|
||||
|
||||
type Field<Source, Key extends string> = {
|
||||
__key: (key: Key) => void;
|
||||
__source: (source: Source) => void;
|
||||
};
|
||||
|
||||
declare const object: <Source>() => <
|
||||
Fields extends {
|
||||
[Key in keyof Fields]: Field<Source, Key & string>;
|
||||
}
|
||||
>(config: {
|
||||
name: string;
|
||||
fields: Fields | (() => Fields);
|
||||
}) => ObjectType<Source>;
|
||||
|
||||
type InferValueFromObjectType<Type extends ObjectType<any>> =
|
||||
Type extends ObjectType<infer Source> ? Source : never;
|
||||
|
||||
type FieldResolver<Source, TType extends ObjectType<any>> = (
|
||||
source: Source
|
||||
) => InferValueFromObjectType<TType>;
|
||||
|
||||
type FieldFuncArgs<Source, Type extends ObjectType<any>> = {
|
||||
type: Type;
|
||||
resolve: FieldResolver<Source, Type>;
|
||||
};
|
||||
|
||||
declare const field: <Source, Type extends ObjectType<any>, Key extends string>(
|
||||
field: FieldFuncArgs<Source, Type>
|
||||
) => Field<Source, Key>;
|
||||
|
||||
type Something = { foo: number };
|
||||
|
||||
const A = object<Something>()({
|
||||
name: "A",
|
||||
fields: () => ({
|
||||
a: field({
|
||||
type: A,
|
||||
resolve() {
|
||||
return {
|
||||
foo: 100,
|
||||
};
|
||||
},
|
||||
}),
|
||||
}),
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user