mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Properly propagate ObjectFlags.NonInferrableType, clean up non-inferrable code paths (#49887)
This commit is contained in:
parent
4902860302
commit
cf3af3febd
@ -785,11 +785,10 @@ namespace ts {
|
||||
const errorTypes = new Map<string, Type>();
|
||||
|
||||
const anyType = createIntrinsicType(TypeFlags.Any, "any");
|
||||
const autoType = createIntrinsicType(TypeFlags.Any, "any");
|
||||
const autoType = createIntrinsicType(TypeFlags.Any, "any", ObjectFlags.NonInferrableType);
|
||||
const wildcardType = createIntrinsicType(TypeFlags.Any, "any");
|
||||
const errorType = createIntrinsicType(TypeFlags.Any, "error");
|
||||
const unresolvedType = createIntrinsicType(TypeFlags.Any, "unresolved");
|
||||
const nonInferrableAnyType = createIntrinsicType(TypeFlags.Any, "any", ObjectFlags.ContainsWideningType);
|
||||
const intrinsicMarkerType = createIntrinsicType(TypeFlags.Any, "intrinsic");
|
||||
const unknownType = createIntrinsicType(TypeFlags.Unknown, "unknown");
|
||||
const nonNullUnknownType = createIntrinsicType(TypeFlags.Unknown, "unknown");
|
||||
@ -818,8 +817,7 @@ namespace ts {
|
||||
const esSymbolType = createIntrinsicType(TypeFlags.ESSymbol, "symbol");
|
||||
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 silentNeverType = createIntrinsicType(TypeFlags.Never, "never", ObjectFlags.NonInferrableType);
|
||||
const implicitNeverType = createIntrinsicType(TypeFlags.Never, "never");
|
||||
const unreachableNeverType = createIntrinsicType(TypeFlags.Never, "never");
|
||||
const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object");
|
||||
@ -9456,11 +9454,7 @@ namespace ts {
|
||||
if (reportErrors && !declarationBelongsToPrivateAmbientMember(element)) {
|
||||
reportImplicitAny(element, anyType);
|
||||
}
|
||||
// When we're including the pattern in the type (an indication we're obtaining a contextual type), we
|
||||
// use the non-inferrable any type. Inference will never directly infer this type, but it is possible
|
||||
// to infer a type that contains it, e.g. for a binding pattern like [foo] or { foo }. In such cases,
|
||||
// widening of the binding pattern type substitutes a regular any for the non-inferrable any.
|
||||
return includePatternInType ? nonInferrableAnyType : anyType;
|
||||
return anyType;
|
||||
}
|
||||
|
||||
// Return the type implied by an object binding pattern
|
||||
@ -13499,12 +13493,12 @@ namespace ts {
|
||||
|
||||
// This function is used to propagate certain flags when creating new object type references and union types.
|
||||
// It is only necessary to do so if a constituent type might be the undefined type, the null type, the type
|
||||
// of an object literal or the anyFunctionType. This is because there are operations in the type checker
|
||||
// of an object literal or a non-inferrable type. This is because there are operations in the type checker
|
||||
// that care about the presence of such types at arbitrary depth in a containing type.
|
||||
function getPropagatingFlagsOfTypes(types: readonly Type[], excludeKinds: TypeFlags): ObjectFlags {
|
||||
function getPropagatingFlagsOfTypes(types: readonly Type[], excludeKinds?: TypeFlags): ObjectFlags {
|
||||
let result: ObjectFlags = 0;
|
||||
for (const type of types) {
|
||||
if (!(type.flags & excludeKinds)) {
|
||||
if (excludeKinds === undefined || !(type.flags & excludeKinds)) {
|
||||
result |= getObjectFlags(type);
|
||||
}
|
||||
}
|
||||
@ -13517,7 +13511,7 @@ namespace ts {
|
||||
if (!type) {
|
||||
type = createObjectType(ObjectFlags.Reference, target.symbol) as TypeReference;
|
||||
target.instantiations.set(id, type);
|
||||
type.objectFlags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0;
|
||||
type.objectFlags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments) : 0;
|
||||
type.target = target;
|
||||
type.resolvedTypeArguments = typeArguments;
|
||||
}
|
||||
@ -17196,6 +17190,7 @@ namespace ts {
|
||||
result.mapper = mapper;
|
||||
result.aliasSymbol = aliasSymbol || type.aliasSymbol;
|
||||
result.aliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(type.aliasTypeArguments, mapper);
|
||||
result.objectFlags |= result.aliasTypeArguments ? getPropagatingFlagsOfTypes(result.aliasTypeArguments) : 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -22422,10 +22417,13 @@ namespace ts {
|
||||
propagationType = savePropagationType;
|
||||
return;
|
||||
}
|
||||
if (source.aliasSymbol && source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol) {
|
||||
// Source and target are types originating in the same generic type alias declaration.
|
||||
// Simply infer from source type arguments to target type arguments.
|
||||
inferFromTypeArguments(source.aliasTypeArguments, target.aliasTypeArguments!, getAliasVariances(source.aliasSymbol));
|
||||
if (source.aliasSymbol && source.aliasSymbol === target.aliasSymbol) {
|
||||
if (source.aliasTypeArguments) {
|
||||
// Source and target are types originating in the same generic type alias declaration.
|
||||
// Simply infer from source type arguments to target type arguments.
|
||||
inferFromTypeArguments(source.aliasTypeArguments, target.aliasTypeArguments!, getAliasVariances(source.aliasSymbol));
|
||||
}
|
||||
// And if there weren't any type arguments, there's no reason to run inference as the types must be the same.
|
||||
return;
|
||||
}
|
||||
if (source === target && source.flags & TypeFlags.UnionOrIntersection) {
|
||||
@ -22481,18 +22479,26 @@ namespace ts {
|
||||
target = getActualTypeVariable(target);
|
||||
}
|
||||
if (target.flags & TypeFlags.TypeVariable) {
|
||||
// If target is a type parameter, make an inference, unless the source type contains
|
||||
// the anyFunctionType (the wildcard type that's used to avoid contextually typing functions).
|
||||
// Because the anyFunctionType is internal, it should not be exposed to the user by adding
|
||||
// it as an inference candidate. Hopefully, a better candidate will come along that does
|
||||
// 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 (source === nonInferrableAnyType || source === silentNeverType || (priority & InferencePriority.ReturnType && (source === autoType || source === autoArrayType)) || isFromInferenceBlockedSource(source)) {
|
||||
// Skip inference if the source is "blocked", which is used by the language service to
|
||||
// prevent inference on nodes currently being edited.
|
||||
if (isFromInferenceBlockedSource(source)) {
|
||||
return;
|
||||
}
|
||||
const inference = getInferenceInfoForType(target);
|
||||
if (inference) {
|
||||
// If target is a type parameter, make an inference, unless the source type contains
|
||||
// a "non-inferrable" type. Types with this flag set are markers used to prevent inference.
|
||||
//
|
||||
// For example:
|
||||
// - anyFunctionType is a wildcard type that's used to avoid contextually typing functions;
|
||||
// it's internal, so should not be exposed to the user by adding it as a candidate.
|
||||
// - autoType (and autoArrayType) is a special "any" used in control flow; like anyFunctionType,
|
||||
// it's internal and should not be observable.
|
||||
// - silentNeverType is returned by getInferredType when instantiating a generic function for
|
||||
// inference (and a type variable has no mapping).
|
||||
//
|
||||
// This flag is infectious; if we produce Box<never> (where never is silentNeverType), Box<never> is
|
||||
// also non-inferrable.
|
||||
if (getObjectFlags(source) & ObjectFlags.NonInferrableType) {
|
||||
return;
|
||||
}
|
||||
@ -23043,21 +23049,18 @@ namespace ts {
|
||||
const sourceLen = sourceSignatures.length;
|
||||
const targetLen = targetSignatures.length;
|
||||
const len = sourceLen < targetLen ? sourceLen : targetLen;
|
||||
const skipParameters = !!(getObjectFlags(source) & ObjectFlags.NonInferrableType);
|
||||
for (let i = 0; i < len; i++) {
|
||||
inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getErasedSignature(targetSignatures[targetLen - len + i]), skipParameters);
|
||||
inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getErasedSignature(targetSignatures[targetLen - len + i]));
|
||||
}
|
||||
}
|
||||
|
||||
function inferFromSignature(source: Signature, target: Signature, skipParameters: boolean) {
|
||||
if (!skipParameters) {
|
||||
const saveBivariant = bivariant;
|
||||
const kind = target.declaration ? target.declaration.kind : SyntaxKind.Unknown;
|
||||
// Once we descend into a bivariant signature we remain bivariant for all nested inferences
|
||||
bivariant = bivariant || kind === SyntaxKind.MethodDeclaration || kind === SyntaxKind.MethodSignature || kind === SyntaxKind.Constructor;
|
||||
applyToParameterTypes(source, target, inferFromContravariantTypes);
|
||||
bivariant = saveBivariant;
|
||||
}
|
||||
function inferFromSignature(source: Signature, target: Signature) {
|
||||
const saveBivariant = bivariant;
|
||||
const kind = target.declaration ? target.declaration.kind : SyntaxKind.Unknown;
|
||||
// Once we descend into a bivariant signature we remain bivariant for all nested inferences
|
||||
bivariant = bivariant || kind === SyntaxKind.MethodDeclaration || kind === SyntaxKind.MethodSignature || kind === SyntaxKind.Constructor;
|
||||
applyToParameterTypes(source, target, inferFromContravariantTypes);
|
||||
bivariant = saveBivariant;
|
||||
applyToReturnTypes(source, target, inferFromTypes);
|
||||
}
|
||||
|
||||
@ -31271,7 +31274,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 nonInferrableType (a type that is assignable to anything and
|
||||
// propagated out and eventually turned into silentNeverType (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);
|
||||
@ -31906,8 +31909,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 nonInferrableType.
|
||||
return nonInferrableType;
|
||||
// returns a function type. We defer checking and return silentNeverType.
|
||||
return silentNeverType;
|
||||
}
|
||||
|
||||
checkDeprecatedSignature(signature, node);
|
||||
|
||||
34
tests/baselines/reference/nonInferrableTypePropagation1.js
Normal file
34
tests/baselines/reference/nonInferrableTypePropagation1.js
Normal file
@ -0,0 +1,34 @@
|
||||
//// [nonInferrableTypePropagation1.ts]
|
||||
type Op<I, O> = (thing: Thing<I>) => Thing<O>;
|
||||
type Thing<T> = {
|
||||
value: T;
|
||||
pipe<A, B>(
|
||||
opA: Op<T, A>,
|
||||
opB: Op<A, B>,
|
||||
): Thing<B>;
|
||||
};
|
||||
type Box<V> = { data: V };
|
||||
|
||||
declare const thing: Thing<number>;
|
||||
|
||||
declare function map<T, R>(project: (value: T) => R): Op<T, R>;
|
||||
declare function tap<T>(next: (value: T) => void): Op<T, T>;
|
||||
declare function box<V>(data: V): Box<V>;
|
||||
declare function createAndUnbox<V>(factory: () => Thing<V | Box<V>>): Thing<V>;
|
||||
declare function log(value: any): void;
|
||||
|
||||
const result1 = createAndUnbox(() => thing.pipe(
|
||||
map((data) => box(data)),
|
||||
tap((v) => log(v)),
|
||||
));
|
||||
|
||||
const result2 = createAndUnbox(() => thing.pipe(
|
||||
tap((v) => log(v)),
|
||||
map((data) => box(data)),
|
||||
));
|
||||
|
||||
|
||||
//// [nonInferrableTypePropagation1.js]
|
||||
"use strict";
|
||||
var result1 = createAndUnbox(function () { return thing.pipe(map(function (data) { return box(data); }), tap(function (v) { return log(v); })); });
|
||||
var result2 = createAndUnbox(function () { return thing.pipe(tap(function (v) { return log(v); }), map(function (data) { return box(data); })); });
|
||||
138
tests/baselines/reference/nonInferrableTypePropagation1.symbols
Normal file
138
tests/baselines/reference/nonInferrableTypePropagation1.symbols
Normal file
@ -0,0 +1,138 @@
|
||||
=== tests/cases/compiler/nonInferrableTypePropagation1.ts ===
|
||||
type Op<I, O> = (thing: Thing<I>) => Thing<O>;
|
||||
>Op : Symbol(Op, Decl(nonInferrableTypePropagation1.ts, 0, 0))
|
||||
>I : Symbol(I, Decl(nonInferrableTypePropagation1.ts, 0, 8))
|
||||
>O : Symbol(O, Decl(nonInferrableTypePropagation1.ts, 0, 10))
|
||||
>thing : Symbol(thing, Decl(nonInferrableTypePropagation1.ts, 0, 17))
|
||||
>Thing : Symbol(Thing, Decl(nonInferrableTypePropagation1.ts, 0, 46))
|
||||
>I : Symbol(I, Decl(nonInferrableTypePropagation1.ts, 0, 8))
|
||||
>Thing : Symbol(Thing, Decl(nonInferrableTypePropagation1.ts, 0, 46))
|
||||
>O : Symbol(O, Decl(nonInferrableTypePropagation1.ts, 0, 10))
|
||||
|
||||
type Thing<T> = {
|
||||
>Thing : Symbol(Thing, Decl(nonInferrableTypePropagation1.ts, 0, 46))
|
||||
>T : Symbol(T, Decl(nonInferrableTypePropagation1.ts, 1, 11))
|
||||
|
||||
value: T;
|
||||
>value : Symbol(value, Decl(nonInferrableTypePropagation1.ts, 1, 17))
|
||||
>T : Symbol(T, Decl(nonInferrableTypePropagation1.ts, 1, 11))
|
||||
|
||||
pipe<A, B>(
|
||||
>pipe : Symbol(pipe, Decl(nonInferrableTypePropagation1.ts, 2, 13))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation1.ts, 3, 9))
|
||||
>B : Symbol(B, Decl(nonInferrableTypePropagation1.ts, 3, 11))
|
||||
|
||||
opA: Op<T, A>,
|
||||
>opA : Symbol(opA, Decl(nonInferrableTypePropagation1.ts, 3, 15))
|
||||
>Op : Symbol(Op, Decl(nonInferrableTypePropagation1.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(nonInferrableTypePropagation1.ts, 1, 11))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation1.ts, 3, 9))
|
||||
|
||||
opB: Op<A, B>,
|
||||
>opB : Symbol(opB, Decl(nonInferrableTypePropagation1.ts, 4, 22))
|
||||
>Op : Symbol(Op, Decl(nonInferrableTypePropagation1.ts, 0, 0))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation1.ts, 3, 9))
|
||||
>B : Symbol(B, Decl(nonInferrableTypePropagation1.ts, 3, 11))
|
||||
|
||||
): Thing<B>;
|
||||
>Thing : Symbol(Thing, Decl(nonInferrableTypePropagation1.ts, 0, 46))
|
||||
>B : Symbol(B, Decl(nonInferrableTypePropagation1.ts, 3, 11))
|
||||
|
||||
};
|
||||
type Box<V> = { data: V };
|
||||
>Box : Symbol(Box, Decl(nonInferrableTypePropagation1.ts, 7, 2))
|
||||
>V : Symbol(V, Decl(nonInferrableTypePropagation1.ts, 8, 9))
|
||||
>data : Symbol(data, Decl(nonInferrableTypePropagation1.ts, 8, 15))
|
||||
>V : Symbol(V, Decl(nonInferrableTypePropagation1.ts, 8, 9))
|
||||
|
||||
declare const thing: Thing<number>;
|
||||
>thing : Symbol(thing, Decl(nonInferrableTypePropagation1.ts, 10, 13))
|
||||
>Thing : Symbol(Thing, Decl(nonInferrableTypePropagation1.ts, 0, 46))
|
||||
|
||||
declare function map<T, R>(project: (value: T) => R): Op<T, R>;
|
||||
>map : Symbol(map, Decl(nonInferrableTypePropagation1.ts, 10, 35))
|
||||
>T : Symbol(T, Decl(nonInferrableTypePropagation1.ts, 12, 21))
|
||||
>R : Symbol(R, Decl(nonInferrableTypePropagation1.ts, 12, 23))
|
||||
>project : Symbol(project, Decl(nonInferrableTypePropagation1.ts, 12, 27))
|
||||
>value : Symbol(value, Decl(nonInferrableTypePropagation1.ts, 12, 37))
|
||||
>T : Symbol(T, Decl(nonInferrableTypePropagation1.ts, 12, 21))
|
||||
>R : Symbol(R, Decl(nonInferrableTypePropagation1.ts, 12, 23))
|
||||
>Op : Symbol(Op, Decl(nonInferrableTypePropagation1.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(nonInferrableTypePropagation1.ts, 12, 21))
|
||||
>R : Symbol(R, Decl(nonInferrableTypePropagation1.ts, 12, 23))
|
||||
|
||||
declare function tap<T>(next: (value: T) => void): Op<T, T>;
|
||||
>tap : Symbol(tap, Decl(nonInferrableTypePropagation1.ts, 12, 63))
|
||||
>T : Symbol(T, Decl(nonInferrableTypePropagation1.ts, 13, 21))
|
||||
>next : Symbol(next, Decl(nonInferrableTypePropagation1.ts, 13, 24))
|
||||
>value : Symbol(value, Decl(nonInferrableTypePropagation1.ts, 13, 31))
|
||||
>T : Symbol(T, Decl(nonInferrableTypePropagation1.ts, 13, 21))
|
||||
>Op : Symbol(Op, Decl(nonInferrableTypePropagation1.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(nonInferrableTypePropagation1.ts, 13, 21))
|
||||
>T : Symbol(T, Decl(nonInferrableTypePropagation1.ts, 13, 21))
|
||||
|
||||
declare function box<V>(data: V): Box<V>;
|
||||
>box : Symbol(box, Decl(nonInferrableTypePropagation1.ts, 13, 60))
|
||||
>V : Symbol(V, Decl(nonInferrableTypePropagation1.ts, 14, 21))
|
||||
>data : Symbol(data, Decl(nonInferrableTypePropagation1.ts, 14, 24))
|
||||
>V : Symbol(V, Decl(nonInferrableTypePropagation1.ts, 14, 21))
|
||||
>Box : Symbol(Box, Decl(nonInferrableTypePropagation1.ts, 7, 2))
|
||||
>V : Symbol(V, Decl(nonInferrableTypePropagation1.ts, 14, 21))
|
||||
|
||||
declare function createAndUnbox<V>(factory: () => Thing<V | Box<V>>): Thing<V>;
|
||||
>createAndUnbox : Symbol(createAndUnbox, Decl(nonInferrableTypePropagation1.ts, 14, 41))
|
||||
>V : Symbol(V, Decl(nonInferrableTypePropagation1.ts, 15, 32))
|
||||
>factory : Symbol(factory, Decl(nonInferrableTypePropagation1.ts, 15, 35))
|
||||
>Thing : Symbol(Thing, Decl(nonInferrableTypePropagation1.ts, 0, 46))
|
||||
>V : Symbol(V, Decl(nonInferrableTypePropagation1.ts, 15, 32))
|
||||
>Box : Symbol(Box, Decl(nonInferrableTypePropagation1.ts, 7, 2))
|
||||
>V : Symbol(V, Decl(nonInferrableTypePropagation1.ts, 15, 32))
|
||||
>Thing : Symbol(Thing, Decl(nonInferrableTypePropagation1.ts, 0, 46))
|
||||
>V : Symbol(V, Decl(nonInferrableTypePropagation1.ts, 15, 32))
|
||||
|
||||
declare function log(value: any): void;
|
||||
>log : Symbol(log, Decl(nonInferrableTypePropagation1.ts, 15, 79))
|
||||
>value : Symbol(value, Decl(nonInferrableTypePropagation1.ts, 16, 21))
|
||||
|
||||
const result1 = createAndUnbox(() => thing.pipe(
|
||||
>result1 : Symbol(result1, Decl(nonInferrableTypePropagation1.ts, 18, 5))
|
||||
>createAndUnbox : Symbol(createAndUnbox, Decl(nonInferrableTypePropagation1.ts, 14, 41))
|
||||
>thing.pipe : Symbol(pipe, Decl(nonInferrableTypePropagation1.ts, 2, 13))
|
||||
>thing : Symbol(thing, Decl(nonInferrableTypePropagation1.ts, 10, 13))
|
||||
>pipe : Symbol(pipe, Decl(nonInferrableTypePropagation1.ts, 2, 13))
|
||||
|
||||
map((data) => box(data)),
|
||||
>map : Symbol(map, Decl(nonInferrableTypePropagation1.ts, 10, 35))
|
||||
>data : Symbol(data, Decl(nonInferrableTypePropagation1.ts, 19, 9))
|
||||
>box : Symbol(box, Decl(nonInferrableTypePropagation1.ts, 13, 60))
|
||||
>data : Symbol(data, Decl(nonInferrableTypePropagation1.ts, 19, 9))
|
||||
|
||||
tap((v) => log(v)),
|
||||
>tap : Symbol(tap, Decl(nonInferrableTypePropagation1.ts, 12, 63))
|
||||
>v : Symbol(v, Decl(nonInferrableTypePropagation1.ts, 20, 9))
|
||||
>log : Symbol(log, Decl(nonInferrableTypePropagation1.ts, 15, 79))
|
||||
>v : Symbol(v, Decl(nonInferrableTypePropagation1.ts, 20, 9))
|
||||
|
||||
));
|
||||
|
||||
const result2 = createAndUnbox(() => thing.pipe(
|
||||
>result2 : Symbol(result2, Decl(nonInferrableTypePropagation1.ts, 23, 5))
|
||||
>createAndUnbox : Symbol(createAndUnbox, Decl(nonInferrableTypePropagation1.ts, 14, 41))
|
||||
>thing.pipe : Symbol(pipe, Decl(nonInferrableTypePropagation1.ts, 2, 13))
|
||||
>thing : Symbol(thing, Decl(nonInferrableTypePropagation1.ts, 10, 13))
|
||||
>pipe : Symbol(pipe, Decl(nonInferrableTypePropagation1.ts, 2, 13))
|
||||
|
||||
tap((v) => log(v)),
|
||||
>tap : Symbol(tap, Decl(nonInferrableTypePropagation1.ts, 12, 63))
|
||||
>v : Symbol(v, Decl(nonInferrableTypePropagation1.ts, 24, 9))
|
||||
>log : Symbol(log, Decl(nonInferrableTypePropagation1.ts, 15, 79))
|
||||
>v : Symbol(v, Decl(nonInferrableTypePropagation1.ts, 24, 9))
|
||||
|
||||
map((data) => box(data)),
|
||||
>map : Symbol(map, Decl(nonInferrableTypePropagation1.ts, 10, 35))
|
||||
>data : Symbol(data, Decl(nonInferrableTypePropagation1.ts, 25, 9))
|
||||
>box : Symbol(box, Decl(nonInferrableTypePropagation1.ts, 13, 60))
|
||||
>data : Symbol(data, Decl(nonInferrableTypePropagation1.ts, 25, 9))
|
||||
|
||||
));
|
||||
|
||||
111
tests/baselines/reference/nonInferrableTypePropagation1.types
Normal file
111
tests/baselines/reference/nonInferrableTypePropagation1.types
Normal file
@ -0,0 +1,111 @@
|
||||
=== tests/cases/compiler/nonInferrableTypePropagation1.ts ===
|
||||
type Op<I, O> = (thing: Thing<I>) => Thing<O>;
|
||||
>Op : Op<I, O>
|
||||
>thing : Thing<I>
|
||||
|
||||
type Thing<T> = {
|
||||
>Thing : Thing<T>
|
||||
|
||||
value: T;
|
||||
>value : T
|
||||
|
||||
pipe<A, B>(
|
||||
>pipe : <A, B>(opA: Op<T, A>, opB: Op<A, B>) => Thing<B>
|
||||
|
||||
opA: Op<T, A>,
|
||||
>opA : Op<T, A>
|
||||
|
||||
opB: Op<A, B>,
|
||||
>opB : Op<A, B>
|
||||
|
||||
): Thing<B>;
|
||||
};
|
||||
type Box<V> = { data: V };
|
||||
>Box : Box<V>
|
||||
>data : V
|
||||
|
||||
declare const thing: Thing<number>;
|
||||
>thing : Thing<number>
|
||||
|
||||
declare function map<T, R>(project: (value: T) => R): Op<T, R>;
|
||||
>map : <T, R>(project: (value: T) => R) => Op<T, R>
|
||||
>project : (value: T) => R
|
||||
>value : T
|
||||
|
||||
declare function tap<T>(next: (value: T) => void): Op<T, T>;
|
||||
>tap : <T>(next: (value: T) => void) => Op<T, T>
|
||||
>next : (value: T) => void
|
||||
>value : T
|
||||
|
||||
declare function box<V>(data: V): Box<V>;
|
||||
>box : <V>(data: V) => Box<V>
|
||||
>data : V
|
||||
|
||||
declare function createAndUnbox<V>(factory: () => Thing<V | Box<V>>): Thing<V>;
|
||||
>createAndUnbox : <V>(factory: () => Thing<V | Box<V>>) => Thing<V>
|
||||
>factory : () => Thing<V | Box<V>>
|
||||
|
||||
declare function log(value: any): void;
|
||||
>log : (value: any) => void
|
||||
>value : any
|
||||
|
||||
const result1 = createAndUnbox(() => thing.pipe(
|
||||
>result1 : Thing<number>
|
||||
>createAndUnbox(() => thing.pipe( map((data) => box(data)), tap((v) => log(v)),)) : Thing<number>
|
||||
>createAndUnbox : <V>(factory: () => Thing<V | Box<V>>) => Thing<V>
|
||||
>() => thing.pipe( map((data) => box(data)), tap((v) => log(v)),) : () => Thing<Box<number>>
|
||||
>thing.pipe( map((data) => box(data)), tap((v) => log(v)),) : Thing<Box<number>>
|
||||
>thing.pipe : <A, B>(opA: Op<number, A>, opB: Op<A, B>) => Thing<B>
|
||||
>thing : Thing<number>
|
||||
>pipe : <A, B>(opA: Op<number, A>, opB: Op<A, B>) => Thing<B>
|
||||
|
||||
map((data) => box(data)),
|
||||
>map((data) => box(data)) : Op<number, Box<number>>
|
||||
>map : <T, R>(project: (value: T) => R) => Op<T, R>
|
||||
>(data) => box(data) : (data: number) => Box<number>
|
||||
>data : number
|
||||
>box(data) : Box<number>
|
||||
>box : <V>(data: V) => Box<V>
|
||||
>data : number
|
||||
|
||||
tap((v) => log(v)),
|
||||
>tap((v) => log(v)) : Op<Box<number>, Box<number>>
|
||||
>tap : <T>(next: (value: T) => void) => Op<T, T>
|
||||
>(v) => log(v) : (v: Box<number>) => void
|
||||
>v : Box<number>
|
||||
>log(v) : void
|
||||
>log : (value: any) => void
|
||||
>v : Box<number>
|
||||
|
||||
));
|
||||
|
||||
const result2 = createAndUnbox(() => thing.pipe(
|
||||
>result2 : Thing<number>
|
||||
>createAndUnbox(() => thing.pipe( tap((v) => log(v)), map((data) => box(data)),)) : Thing<number>
|
||||
>createAndUnbox : <V>(factory: () => Thing<V | Box<V>>) => Thing<V>
|
||||
>() => thing.pipe( tap((v) => log(v)), map((data) => box(data)),) : () => Thing<Box<number>>
|
||||
>thing.pipe( tap((v) => log(v)), map((data) => box(data)),) : Thing<Box<number>>
|
||||
>thing.pipe : <A, B>(opA: Op<number, A>, opB: Op<A, B>) => Thing<B>
|
||||
>thing : Thing<number>
|
||||
>pipe : <A, B>(opA: Op<number, A>, opB: Op<A, B>) => Thing<B>
|
||||
|
||||
tap((v) => log(v)),
|
||||
>tap((v) => log(v)) : Op<number, number>
|
||||
>tap : <T>(next: (value: T) => void) => Op<T, T>
|
||||
>(v) => log(v) : (v: number) => void
|
||||
>v : number
|
||||
>log(v) : void
|
||||
>log : (value: any) => void
|
||||
>v : number
|
||||
|
||||
map((data) => box(data)),
|
||||
>map((data) => box(data)) : Op<number, Box<number>>
|
||||
>map : <T, R>(project: (value: T) => R) => Op<T, R>
|
||||
>(data) => box(data) : (data: number) => Box<number>
|
||||
>data : number
|
||||
>box(data) : Box<number>
|
||||
>box : <V>(data: V) => Box<V>
|
||||
>data : number
|
||||
|
||||
));
|
||||
|
||||
38
tests/baselines/reference/nonInferrableTypePropagation2.js
Normal file
38
tests/baselines/reference/nonInferrableTypePropagation2.js
Normal file
@ -0,0 +1,38 @@
|
||||
//// [nonInferrableTypePropagation2.ts]
|
||||
export interface Predicate<A> {
|
||||
(a: A): boolean
|
||||
}
|
||||
|
||||
interface Left<E> {
|
||||
readonly _tag: 'Left'
|
||||
readonly left: E
|
||||
}
|
||||
|
||||
interface Right<A> {
|
||||
readonly _tag: 'Right'
|
||||
readonly right: A
|
||||
}
|
||||
|
||||
type Either<E, A> = Left<E> | Right<A>;
|
||||
|
||||
interface Refinement<A, B extends A> {
|
||||
(a: A): a is B
|
||||
}
|
||||
|
||||
declare const filter: {
|
||||
<A, B extends A>(refinement: Refinement<A, B>): (as: ReadonlyArray<A>) => ReadonlyArray<B>
|
||||
<A>(predicate: Predicate<A>): <B extends A>(bs: ReadonlyArray<B>) => ReadonlyArray<B>
|
||||
<A>(predicate: Predicate<A>): (as: ReadonlyArray<A>) => ReadonlyArray<A>
|
||||
};
|
||||
|
||||
declare function pipe<A, B>(a: A, ab: (a: A) => B): B;
|
||||
declare function exists<A>(predicate: Predicate<A>): <E>(ma: Either<E, A>) => boolean;
|
||||
|
||||
declare const es: Either<string, number>[];
|
||||
const x = pipe(es, filter(exists((n) => n > 0)))
|
||||
|
||||
|
||||
//// [nonInferrableTypePropagation2.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var x = pipe(es, filter(exists(function (n) { return n > 0; })));
|
||||
136
tests/baselines/reference/nonInferrableTypePropagation2.symbols
Normal file
136
tests/baselines/reference/nonInferrableTypePropagation2.symbols
Normal file
@ -0,0 +1,136 @@
|
||||
=== tests/cases/compiler/nonInferrableTypePropagation2.ts ===
|
||||
export interface Predicate<A> {
|
||||
>Predicate : Symbol(Predicate, Decl(nonInferrableTypePropagation2.ts, 0, 0))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 0, 27))
|
||||
|
||||
(a: A): boolean
|
||||
>a : Symbol(a, Decl(nonInferrableTypePropagation2.ts, 1, 5))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 0, 27))
|
||||
}
|
||||
|
||||
interface Left<E> {
|
||||
>Left : Symbol(Left, Decl(nonInferrableTypePropagation2.ts, 2, 1))
|
||||
>E : Symbol(E, Decl(nonInferrableTypePropagation2.ts, 4, 15))
|
||||
|
||||
readonly _tag: 'Left'
|
||||
>_tag : Symbol(Left._tag, Decl(nonInferrableTypePropagation2.ts, 4, 19))
|
||||
|
||||
readonly left: E
|
||||
>left : Symbol(Left.left, Decl(nonInferrableTypePropagation2.ts, 5, 25))
|
||||
>E : Symbol(E, Decl(nonInferrableTypePropagation2.ts, 4, 15))
|
||||
}
|
||||
|
||||
interface Right<A> {
|
||||
>Right : Symbol(Right, Decl(nonInferrableTypePropagation2.ts, 7, 1))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 9, 16))
|
||||
|
||||
readonly _tag: 'Right'
|
||||
>_tag : Symbol(Right._tag, Decl(nonInferrableTypePropagation2.ts, 9, 20))
|
||||
|
||||
readonly right: A
|
||||
>right : Symbol(Right.right, Decl(nonInferrableTypePropagation2.ts, 10, 26))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 9, 16))
|
||||
}
|
||||
|
||||
type Either<E, A> = Left<E> | Right<A>;
|
||||
>Either : Symbol(Either, Decl(nonInferrableTypePropagation2.ts, 12, 1))
|
||||
>E : Symbol(E, Decl(nonInferrableTypePropagation2.ts, 14, 12))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 14, 14))
|
||||
>Left : Symbol(Left, Decl(nonInferrableTypePropagation2.ts, 2, 1))
|
||||
>E : Symbol(E, Decl(nonInferrableTypePropagation2.ts, 14, 12))
|
||||
>Right : Symbol(Right, Decl(nonInferrableTypePropagation2.ts, 7, 1))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 14, 14))
|
||||
|
||||
interface Refinement<A, B extends A> {
|
||||
>Refinement : Symbol(Refinement, Decl(nonInferrableTypePropagation2.ts, 14, 39))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 16, 21))
|
||||
>B : Symbol(B, Decl(nonInferrableTypePropagation2.ts, 16, 23))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 16, 21))
|
||||
|
||||
(a: A): a is B
|
||||
>a : Symbol(a, Decl(nonInferrableTypePropagation2.ts, 17, 5))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 16, 21))
|
||||
>a : Symbol(a, Decl(nonInferrableTypePropagation2.ts, 17, 5))
|
||||
>B : Symbol(B, Decl(nonInferrableTypePropagation2.ts, 16, 23))
|
||||
}
|
||||
|
||||
declare const filter: {
|
||||
>filter : Symbol(filter, Decl(nonInferrableTypePropagation2.ts, 20, 13))
|
||||
|
||||
<A, B extends A>(refinement: Refinement<A, B>): (as: ReadonlyArray<A>) => ReadonlyArray<B>
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 21, 5))
|
||||
>B : Symbol(B, Decl(nonInferrableTypePropagation2.ts, 21, 7))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 21, 5))
|
||||
>refinement : Symbol(refinement, Decl(nonInferrableTypePropagation2.ts, 21, 21))
|
||||
>Refinement : Symbol(Refinement, Decl(nonInferrableTypePropagation2.ts, 14, 39))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 21, 5))
|
||||
>B : Symbol(B, Decl(nonInferrableTypePropagation2.ts, 21, 7))
|
||||
>as : Symbol(as, Decl(nonInferrableTypePropagation2.ts, 21, 53))
|
||||
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 21, 5))
|
||||
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --))
|
||||
>B : Symbol(B, Decl(nonInferrableTypePropagation2.ts, 21, 7))
|
||||
|
||||
<A>(predicate: Predicate<A>): <B extends A>(bs: ReadonlyArray<B>) => ReadonlyArray<B>
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 22, 5))
|
||||
>predicate : Symbol(predicate, Decl(nonInferrableTypePropagation2.ts, 22, 8))
|
||||
>Predicate : Symbol(Predicate, Decl(nonInferrableTypePropagation2.ts, 0, 0))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 22, 5))
|
||||
>B : Symbol(B, Decl(nonInferrableTypePropagation2.ts, 22, 35))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 22, 5))
|
||||
>bs : Symbol(bs, Decl(nonInferrableTypePropagation2.ts, 22, 48))
|
||||
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --))
|
||||
>B : Symbol(B, Decl(nonInferrableTypePropagation2.ts, 22, 35))
|
||||
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --))
|
||||
>B : Symbol(B, Decl(nonInferrableTypePropagation2.ts, 22, 35))
|
||||
|
||||
<A>(predicate: Predicate<A>): (as: ReadonlyArray<A>) => ReadonlyArray<A>
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 23, 5))
|
||||
>predicate : Symbol(predicate, Decl(nonInferrableTypePropagation2.ts, 23, 8))
|
||||
>Predicate : Symbol(Predicate, Decl(nonInferrableTypePropagation2.ts, 0, 0))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 23, 5))
|
||||
>as : Symbol(as, Decl(nonInferrableTypePropagation2.ts, 23, 35))
|
||||
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 23, 5))
|
||||
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 23, 5))
|
||||
|
||||
};
|
||||
|
||||
declare function pipe<A, B>(a: A, ab: (a: A) => B): B;
|
||||
>pipe : Symbol(pipe, Decl(nonInferrableTypePropagation2.ts, 24, 2))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 26, 22))
|
||||
>B : Symbol(B, Decl(nonInferrableTypePropagation2.ts, 26, 24))
|
||||
>a : Symbol(a, Decl(nonInferrableTypePropagation2.ts, 26, 28))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 26, 22))
|
||||
>ab : Symbol(ab, Decl(nonInferrableTypePropagation2.ts, 26, 33))
|
||||
>a : Symbol(a, Decl(nonInferrableTypePropagation2.ts, 26, 39))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 26, 22))
|
||||
>B : Symbol(B, Decl(nonInferrableTypePropagation2.ts, 26, 24))
|
||||
>B : Symbol(B, Decl(nonInferrableTypePropagation2.ts, 26, 24))
|
||||
|
||||
declare function exists<A>(predicate: Predicate<A>): <E>(ma: Either<E, A>) => boolean;
|
||||
>exists : Symbol(exists, Decl(nonInferrableTypePropagation2.ts, 26, 54))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 27, 24))
|
||||
>predicate : Symbol(predicate, Decl(nonInferrableTypePropagation2.ts, 27, 27))
|
||||
>Predicate : Symbol(Predicate, Decl(nonInferrableTypePropagation2.ts, 0, 0))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 27, 24))
|
||||
>E : Symbol(E, Decl(nonInferrableTypePropagation2.ts, 27, 54))
|
||||
>ma : Symbol(ma, Decl(nonInferrableTypePropagation2.ts, 27, 57))
|
||||
>Either : Symbol(Either, Decl(nonInferrableTypePropagation2.ts, 12, 1))
|
||||
>E : Symbol(E, Decl(nonInferrableTypePropagation2.ts, 27, 54))
|
||||
>A : Symbol(A, Decl(nonInferrableTypePropagation2.ts, 27, 24))
|
||||
|
||||
declare const es: Either<string, number>[];
|
||||
>es : Symbol(es, Decl(nonInferrableTypePropagation2.ts, 29, 13))
|
||||
>Either : Symbol(Either, Decl(nonInferrableTypePropagation2.ts, 12, 1))
|
||||
|
||||
const x = pipe(es, filter(exists((n) => n > 0)))
|
||||
>x : Symbol(x, Decl(nonInferrableTypePropagation2.ts, 30, 5))
|
||||
>pipe : Symbol(pipe, Decl(nonInferrableTypePropagation2.ts, 24, 2))
|
||||
>es : Symbol(es, Decl(nonInferrableTypePropagation2.ts, 29, 13))
|
||||
>filter : Symbol(filter, Decl(nonInferrableTypePropagation2.ts, 20, 13))
|
||||
>exists : Symbol(exists, Decl(nonInferrableTypePropagation2.ts, 26, 54))
|
||||
>n : Symbol(n, Decl(nonInferrableTypePropagation2.ts, 30, 34))
|
||||
>n : Symbol(n, Decl(nonInferrableTypePropagation2.ts, 30, 34))
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
=== tests/cases/compiler/nonInferrableTypePropagation2.ts ===
|
||||
export interface Predicate<A> {
|
||||
(a: A): boolean
|
||||
>a : A
|
||||
}
|
||||
|
||||
interface Left<E> {
|
||||
readonly _tag: 'Left'
|
||||
>_tag : "Left"
|
||||
|
||||
readonly left: E
|
||||
>left : E
|
||||
}
|
||||
|
||||
interface Right<A> {
|
||||
readonly _tag: 'Right'
|
||||
>_tag : "Right"
|
||||
|
||||
readonly right: A
|
||||
>right : A
|
||||
}
|
||||
|
||||
type Either<E, A> = Left<E> | Right<A>;
|
||||
>Either : Either<E, A>
|
||||
|
||||
interface Refinement<A, B extends A> {
|
||||
(a: A): a is B
|
||||
>a : A
|
||||
}
|
||||
|
||||
declare const filter: {
|
||||
>filter : { <A, B extends A>(refinement: Refinement<A, B>): (as: readonly A[]) => readonly B[]; <A>(predicate: Predicate<A>): <B extends A>(bs: readonly B[]) => readonly B[]; <A>(predicate: Predicate<A>): (as: readonly A[]) => readonly A[]; }
|
||||
|
||||
<A, B extends A>(refinement: Refinement<A, B>): (as: ReadonlyArray<A>) => ReadonlyArray<B>
|
||||
>refinement : Refinement<A, B>
|
||||
>as : readonly A[]
|
||||
|
||||
<A>(predicate: Predicate<A>): <B extends A>(bs: ReadonlyArray<B>) => ReadonlyArray<B>
|
||||
>predicate : Predicate<A>
|
||||
>bs : readonly B[]
|
||||
|
||||
<A>(predicate: Predicate<A>): (as: ReadonlyArray<A>) => ReadonlyArray<A>
|
||||
>predicate : Predicate<A>
|
||||
>as : readonly A[]
|
||||
|
||||
};
|
||||
|
||||
declare function pipe<A, B>(a: A, ab: (a: A) => B): B;
|
||||
>pipe : <A, B>(a: A, ab: (a: A) => B) => B
|
||||
>a : A
|
||||
>ab : (a: A) => B
|
||||
>a : A
|
||||
|
||||
declare function exists<A>(predicate: Predicate<A>): <E>(ma: Either<E, A>) => boolean;
|
||||
>exists : <A>(predicate: Predicate<A>) => <E>(ma: Either<E, A>) => boolean
|
||||
>predicate : Predicate<A>
|
||||
>ma : Either<E, A>
|
||||
|
||||
declare const es: Either<string, number>[];
|
||||
>es : Either<string, number>[]
|
||||
|
||||
const x = pipe(es, filter(exists((n) => n > 0)))
|
||||
>x : readonly Either<string, number>[]
|
||||
>pipe(es, filter(exists((n) => n > 0))) : readonly Either<string, number>[]
|
||||
>pipe : <A, B>(a: A, ab: (a: A) => B) => B
|
||||
>es : Either<string, number>[]
|
||||
>filter(exists((n) => n > 0)) : (as: readonly Either<string, number>[]) => readonly Either<string, number>[]
|
||||
>filter : { <A, B extends A>(refinement: Refinement<A, B>): (as: readonly A[]) => readonly B[]; <A>(predicate: Predicate<A>): <B extends A>(bs: readonly B[]) => readonly B[]; <A>(predicate: Predicate<A>): (as: readonly A[]) => readonly A[]; }
|
||||
>exists((n) => n > 0) : <E>(ma: Either<E, number>) => boolean
|
||||
>exists : <A>(predicate: Predicate<A>) => <E>(ma: Either<E, A>) => boolean
|
||||
>(n) => n > 0 : (n: number) => boolean
|
||||
>n : number
|
||||
>n > 0 : boolean
|
||||
>n : number
|
||||
>0 : 0
|
||||
|
||||
29
tests/cases/compiler/nonInferrableTypePropagation1.ts
Normal file
29
tests/cases/compiler/nonInferrableTypePropagation1.ts
Normal file
@ -0,0 +1,29 @@
|
||||
// @strict: true
|
||||
|
||||
type Op<I, O> = (thing: Thing<I>) => Thing<O>;
|
||||
type Thing<T> = {
|
||||
value: T;
|
||||
pipe<A, B>(
|
||||
opA: Op<T, A>,
|
||||
opB: Op<A, B>,
|
||||
): Thing<B>;
|
||||
};
|
||||
type Box<V> = { data: V };
|
||||
|
||||
declare const thing: Thing<number>;
|
||||
|
||||
declare function map<T, R>(project: (value: T) => R): Op<T, R>;
|
||||
declare function tap<T>(next: (value: T) => void): Op<T, T>;
|
||||
declare function box<V>(data: V): Box<V>;
|
||||
declare function createAndUnbox<V>(factory: () => Thing<V | Box<V>>): Thing<V>;
|
||||
declare function log(value: any): void;
|
||||
|
||||
const result1 = createAndUnbox(() => thing.pipe(
|
||||
map((data) => box(data)),
|
||||
tap((v) => log(v)),
|
||||
));
|
||||
|
||||
const result2 = createAndUnbox(() => thing.pipe(
|
||||
tap((v) => log(v)),
|
||||
map((data) => box(data)),
|
||||
));
|
||||
33
tests/cases/compiler/nonInferrableTypePropagation2.ts
Normal file
33
tests/cases/compiler/nonInferrableTypePropagation2.ts
Normal file
@ -0,0 +1,33 @@
|
||||
// @strict: true
|
||||
|
||||
export interface Predicate<A> {
|
||||
(a: A): boolean
|
||||
}
|
||||
|
||||
interface Left<E> {
|
||||
readonly _tag: 'Left'
|
||||
readonly left: E
|
||||
}
|
||||
|
||||
interface Right<A> {
|
||||
readonly _tag: 'Right'
|
||||
readonly right: A
|
||||
}
|
||||
|
||||
type Either<E, A> = Left<E> | Right<A>;
|
||||
|
||||
interface Refinement<A, B extends A> {
|
||||
(a: A): a is B
|
||||
}
|
||||
|
||||
declare const filter: {
|
||||
<A, B extends A>(refinement: Refinement<A, B>): (as: ReadonlyArray<A>) => ReadonlyArray<B>
|
||||
<A>(predicate: Predicate<A>): <B extends A>(bs: ReadonlyArray<B>) => ReadonlyArray<B>
|
||||
<A>(predicate: Predicate<A>): (as: ReadonlyArray<A>) => ReadonlyArray<A>
|
||||
};
|
||||
|
||||
declare function pipe<A, B>(a: A, ab: (a: A) => B): B;
|
||||
declare function exists<A>(predicate: Predicate<A>): <E>(ma: Either<E, A>) => boolean;
|
||||
|
||||
declare const es: Either<string, number>[];
|
||||
const x = pipe(es, filter(exists((n) => n > 0)))
|
||||
Loading…
x
Reference in New Issue
Block a user