mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
Measure variance of aliased conditional types using variance markers (#27804)
* Measure variance of aliased conditional types using variance markers * Just do variance probing for all type aliases * Small limiter for predictability * Inline property set, remove unused functions
This commit is contained in:
parent
ccc16136b2
commit
e2100cd2cc
@ -7636,35 +7636,35 @@ namespace ts {
|
||||
* @param typeParameters The requested type parameters.
|
||||
* @param minTypeArgumentCount The minimum number of required type arguments.
|
||||
*/
|
||||
function fillMissingTypeArguments(typeArguments: Type[], typeParameters: ReadonlyArray<TypeParameter> | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean): Type[];
|
||||
function fillMissingTypeArguments(typeArguments: Type[] | undefined, typeParameters: ReadonlyArray<TypeParameter> | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean): Type[] | undefined;
|
||||
function fillMissingTypeArguments(typeArguments: Type[] | undefined, typeParameters: ReadonlyArray<TypeParameter> | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean) {
|
||||
function fillMissingTypeArguments(typeArguments: ReadonlyArray<Type>, typeParameters: ReadonlyArray<TypeParameter> | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean): Type[];
|
||||
function fillMissingTypeArguments(typeArguments: ReadonlyArray<Type> | undefined, typeParameters: ReadonlyArray<TypeParameter> | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean): Type[] | undefined;
|
||||
function fillMissingTypeArguments(typeArguments: ReadonlyArray<Type> | undefined, typeParameters: ReadonlyArray<TypeParameter> | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean) {
|
||||
const numTypeParameters = length(typeParameters);
|
||||
if (numTypeParameters) {
|
||||
const numTypeArguments = length(typeArguments);
|
||||
if (isJavaScriptImplicitAny || (numTypeArguments >= minTypeArgumentCount && numTypeArguments <= numTypeParameters)) {
|
||||
if (!typeArguments) {
|
||||
typeArguments = [];
|
||||
}
|
||||
|
||||
// Map an unsatisfied type parameter with a default type.
|
||||
// If a type parameter does not have a default type, or if the default type
|
||||
// is a forward reference, the empty object type is used.
|
||||
for (let i = numTypeArguments; i < numTypeParameters; i++) {
|
||||
typeArguments[i] = getDefaultTypeArgumentType(isJavaScriptImplicitAny);
|
||||
}
|
||||
for (let i = numTypeArguments; i < numTypeParameters; i++) {
|
||||
const mapper = createTypeMapper(typeParameters!, typeArguments);
|
||||
let defaultType = getDefaultFromTypeParameter(typeParameters![i]);
|
||||
if (isJavaScriptImplicitAny && defaultType && isTypeIdenticalTo(defaultType, emptyObjectType)) {
|
||||
defaultType = anyType;
|
||||
}
|
||||
typeArguments[i] = defaultType ? instantiateType(defaultType, mapper) : getDefaultTypeArgumentType(isJavaScriptImplicitAny);
|
||||
}
|
||||
typeArguments.length = typeParameters!.length;
|
||||
}
|
||||
if (!numTypeParameters) {
|
||||
return [];
|
||||
}
|
||||
return typeArguments;
|
||||
const numTypeArguments = length(typeArguments);
|
||||
if (isJavaScriptImplicitAny || (numTypeArguments >= minTypeArgumentCount && numTypeArguments <= numTypeParameters)) {
|
||||
const result = typeArguments ? typeArguments.slice() : [];
|
||||
|
||||
// Map an unsatisfied type parameter with a default type.
|
||||
// If a type parameter does not have a default type, or if the default type
|
||||
// is a forward reference, the empty object type is used.
|
||||
for (let i = numTypeArguments; i < numTypeParameters; i++) {
|
||||
result[i] = getDefaultTypeArgumentType(isJavaScriptImplicitAny);
|
||||
}
|
||||
for (let i = numTypeArguments; i < numTypeParameters; i++) {
|
||||
const mapper = createTypeMapper(typeParameters!, result);
|
||||
let defaultType = getDefaultFromTypeParameter(typeParameters![i]);
|
||||
if (isJavaScriptImplicitAny && defaultType && isTypeIdenticalTo(defaultType, emptyObjectType)) {
|
||||
defaultType = anyType;
|
||||
}
|
||||
result[i] = defaultType ? instantiateType(defaultType, mapper) : getDefaultTypeArgumentType(isJavaScriptImplicitAny);
|
||||
}
|
||||
result.length = typeParameters!.length;
|
||||
return result;
|
||||
}
|
||||
return typeArguments && typeArguments.slice();
|
||||
}
|
||||
|
||||
function getSignatureFromDeclaration(declaration: SignatureDeclaration | JSDocSignature): Signature {
|
||||
@ -8262,7 +8262,7 @@ namespace ts {
|
||||
return checkNoTypeArguments(node, symbol) ? type : errorType;
|
||||
}
|
||||
|
||||
function getTypeAliasInstantiation(symbol: Symbol, typeArguments: Type[] | undefined): Type {
|
||||
function getTypeAliasInstantiation(symbol: Symbol, typeArguments: ReadonlyArray<Type> | undefined): Type {
|
||||
const type = getDeclaredTypeOfSymbol(symbol);
|
||||
const links = getSymbolLinks(symbol);
|
||||
const typeParameters = links.typeParameters!;
|
||||
@ -11783,9 +11783,7 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function typeArgumentsRelatedTo(source: TypeReference, target: TypeReference, variances: Variance[], reportErrors: boolean): Ternary {
|
||||
const sources = source.typeArguments || emptyArray;
|
||||
const targets = target.typeArguments || emptyArray;
|
||||
function typeArgumentsRelatedTo(sources: ReadonlyArray<Type> = emptyArray, targets: ReadonlyArray<Type> = emptyArray, variances: ReadonlyArray<Variance> = emptyArray, reportErrors: boolean): Ternary {
|
||||
if (sources.length !== targets.length && relation === identityRelation) {
|
||||
return Ternary.False;
|
||||
}
|
||||
@ -11938,9 +11936,25 @@ namespace ts {
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
|
||||
let result: Ternary;
|
||||
let originalErrorInfo: DiagnosticMessageChain | undefined;
|
||||
const saveErrorInfo = errorInfo;
|
||||
|
||||
// We limit alias variance probing to only object and conditional types since their alias behavior
|
||||
// is more predictable than other, interned types, which may or may not have an alias depending on
|
||||
// the order in which things were checked.
|
||||
if (source.flags & (TypeFlags.Object | TypeFlags.Conditional) && source.aliasSymbol &&
|
||||
source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol &&
|
||||
!(source.aliasTypeArgumentsContainsMarker || target.aliasTypeArgumentsContainsMarker)) {
|
||||
const variances = getAliasVariances(source.aliasSymbol);
|
||||
if (result = typeArgumentsRelatedTo(source.aliasTypeArguments, target.aliasTypeArguments, variances, reportErrors)) {
|
||||
return result;
|
||||
}
|
||||
originalErrorInfo = errorInfo;
|
||||
errorInfo = saveErrorInfo;
|
||||
}
|
||||
|
||||
if (target.flags & TypeFlags.TypeParameter) {
|
||||
// A source type { [P in keyof T]: X } is related to a target type T if X is related to T[P].
|
||||
if (getObjectFlags(source) & ObjectFlags.Mapped && getConstraintTypeFromMappedType(<MappedType>source) === getIndexType(target)) {
|
||||
@ -12101,7 +12115,7 @@ namespace ts {
|
||||
// type references (which are intended by be compared structurally). Obtain the variance
|
||||
// information for the type parameters and relate the type arguments accordingly.
|
||||
const variances = getVariances((<TypeReference>source).target);
|
||||
if (result = typeArgumentsRelatedTo(<TypeReference>source, <TypeReference>target, variances, reportErrors)) {
|
||||
if (result = typeArgumentsRelatedTo((<TypeReference>source).typeArguments, (<TypeReference>target).typeArguments, variances, reportErrors)) {
|
||||
return result;
|
||||
}
|
||||
// The type arguments did not relate appropriately, but it may be because we have no variance
|
||||
@ -12608,48 +12622,58 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function getAliasVariances(symbol: Symbol) {
|
||||
const links = getSymbolLinks(symbol);
|
||||
return getVariancesWorker(links.typeParameters, links, (_links, param, marker) => {
|
||||
const type = getTypeAliasInstantiation(symbol, instantiateTypes(links.typeParameters!, makeUnaryTypeMapper(param, marker)));
|
||||
type.aliasTypeArgumentsContainsMarker = true;
|
||||
return type;
|
||||
});
|
||||
}
|
||||
|
||||
// Return an array containing the variance of each type parameter. The variance is effectively
|
||||
// a digest of the type comparisons that occur for each type argument when instantiations of the
|
||||
// generic type are structurally compared. We infer the variance information by comparing
|
||||
// instantiations of the generic type for type arguments with known relations. The function
|
||||
// returns the emptyArray singleton if we're not in strictFunctionTypes mode or if the function
|
||||
// has been invoked recursively for the given generic type.
|
||||
function getVariancesWorker<TCache extends { variances?: Variance[] }>(typeParameters: ReadonlyArray<TypeParameter> = emptyArray, cache: TCache, createMarkerType: (input: TCache, param: TypeParameter, marker: Type) => Type): Variance[] {
|
||||
let variances = cache.variances;
|
||||
if (!variances) {
|
||||
// The emptyArray singleton is used to signal a recursive invocation.
|
||||
cache.variances = emptyArray;
|
||||
variances = [];
|
||||
for (const tp of typeParameters) {
|
||||
// We first compare instantiations where the type parameter is replaced with
|
||||
// marker types that have a known subtype relationship. From this we can infer
|
||||
// invariance, covariance, contravariance or bivariance.
|
||||
const typeWithSuper = createMarkerType(cache, tp, markerSuperType);
|
||||
const typeWithSub = createMarkerType(cache, tp, markerSubType);
|
||||
let variance = (isTypeAssignableTo(typeWithSub, typeWithSuper) ? Variance.Covariant : 0) |
|
||||
(isTypeAssignableTo(typeWithSuper, typeWithSub) ? Variance.Contravariant : 0);
|
||||
// If the instantiations appear to be related bivariantly it may be because the
|
||||
// type parameter is independent (i.e. it isn't witnessed anywhere in the generic
|
||||
// type). To determine this we compare instantiations where the type parameter is
|
||||
// replaced with marker types that are known to be unrelated.
|
||||
if (variance === Variance.Bivariant && isTypeAssignableTo(createMarkerType(cache, tp, markerOtherType), typeWithSuper)) {
|
||||
variance = Variance.Independent;
|
||||
}
|
||||
variances.push(variance);
|
||||
}
|
||||
cache.variances = variances;
|
||||
}
|
||||
return variances;
|
||||
}
|
||||
|
||||
function getVariances(type: GenericType): Variance[] {
|
||||
if (!strictFunctionTypes) {
|
||||
return emptyArray;
|
||||
}
|
||||
const typeParameters = type.typeParameters || emptyArray;
|
||||
let variances = type.variances;
|
||||
if (!variances) {
|
||||
if (type === globalArrayType || type === globalReadonlyArrayType) {
|
||||
// Arrays are known to be covariant, no need to spend time computing this
|
||||
variances = [Variance.Covariant];
|
||||
}
|
||||
else {
|
||||
// The emptyArray singleton is used to signal a recursive invocation.
|
||||
type.variances = emptyArray;
|
||||
variances = [];
|
||||
for (const tp of typeParameters) {
|
||||
// We first compare instantiations where the type parameter is replaced with
|
||||
// marker types that have a known subtype relationship. From this we can infer
|
||||
// invariance, covariance, contravariance or bivariance.
|
||||
const typeWithSuper = getMarkerTypeReference(type, tp, markerSuperType);
|
||||
const typeWithSub = getMarkerTypeReference(type, tp, markerSubType);
|
||||
let variance = (isTypeAssignableTo(typeWithSub, typeWithSuper) ? Variance.Covariant : 0) |
|
||||
(isTypeAssignableTo(typeWithSuper, typeWithSub) ? Variance.Contravariant : 0);
|
||||
// If the instantiations appear to be related bivariantly it may be because the
|
||||
// type parameter is independent (i.e. it isn't witnessed anywhere in the generic
|
||||
// type). To determine this we compare instantiations where the type parameter is
|
||||
// replaced with marker types that are known to be unrelated.
|
||||
if (variance === Variance.Bivariant && isTypeAssignableTo(getMarkerTypeReference(type, tp, markerOtherType), typeWithSuper)) {
|
||||
variance = Variance.Independent;
|
||||
}
|
||||
variances.push(variance);
|
||||
}
|
||||
}
|
||||
type.variances = variances;
|
||||
if (type === globalArrayType || type === globalReadonlyArrayType) {
|
||||
// Arrays are known to be covariant, no need to spend time computing this (emptyArray implies covariance for all parameters)
|
||||
return emptyArray;
|
||||
}
|
||||
return variances;
|
||||
return getVariancesWorker(type.typeParameters, type, getMarkerTypeReference);
|
||||
}
|
||||
|
||||
// Return true if the given type reference has a 'void' type argument for a covariant type parameter.
|
||||
|
||||
@ -3647,6 +3647,7 @@ namespace ts {
|
||||
originatingImport?: ImportDeclaration | ImportCall; // Import declaration which produced the symbol, present if the symbol is marked as uncallable but had call signatures in `resolveESModuleSymbol`
|
||||
lateSymbol?: Symbol; // Late-bound symbol for a computed property
|
||||
specifierCache?: Map<string>; // For symbols corresponding to external modules, a cache of incoming path -> module specifier name mappings
|
||||
variances?: Variance[]; // Alias symbol type argument variance cache
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@ -3899,6 +3900,7 @@ namespace ts {
|
||||
pattern?: DestructuringPattern; // Destructuring pattern represented by type (if any)
|
||||
aliasSymbol?: Symbol; // Alias associated with type
|
||||
aliasTypeArguments?: ReadonlyArray<Type>; // Alias type arguments (if any)
|
||||
/* @internal */ aliasTypeArgumentsContainsMarker?: boolean; // Alias type arguments (if any)
|
||||
/* @internal */
|
||||
wildcardInstantiation?: Type; // Instantiation with type parameters mapped to wildcard type
|
||||
/* @internal */
|
||||
|
||||
152
tests/baselines/reference/conditionalTypeDoesntSpinForever.js
Normal file
152
tests/baselines/reference/conditionalTypeDoesntSpinForever.js
Normal file
@ -0,0 +1,152 @@
|
||||
//// [conditionalTypeDoesntSpinForever.ts]
|
||||
// A *self-contained* demonstration of the problem follows...
|
||||
// Test this by running `tsc --target es6` on the command-line, rather than through another build tool such as Gulp, Webpack, etc.
|
||||
|
||||
export enum PubSubRecordIsStoredInRedisAsA {
|
||||
redisHash = "redisHash",
|
||||
jsonEncodedRedisString = "jsonEncodedRedisString"
|
||||
}
|
||||
|
||||
export interface PubSubRecord<NAME extends string, RECORD, IDENTIFIER extends Partial<RECORD>> {
|
||||
name: NAME;
|
||||
record: RECORD;
|
||||
identifier: IDENTIFIER;
|
||||
storedAs: PubSubRecordIsStoredInRedisAsA;
|
||||
maxMsToWaitBeforePublishing: number;
|
||||
}
|
||||
|
||||
type NameFieldConstructor<SO_FAR> =
|
||||
SO_FAR extends {name: any} ? {} : {
|
||||
name: <TYPE>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & {name: TYPE}>
|
||||
}
|
||||
|
||||
const buildNameFieldConstructor = <SO_FAR>(soFar: SO_FAR) => (
|
||||
"name" in soFar ? {} : {
|
||||
name: <TYPE>(instance: TYPE = undefined) =>
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType<SO_FAR & {name: TYPE}>
|
||||
}
|
||||
);
|
||||
|
||||
type StoredAsConstructor<SO_FAR> =
|
||||
SO_FAR extends {storedAs: any} ? {} : {
|
||||
storedAsJsonEncodedRedisString: () => BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}>;
|
||||
storedRedisHash: () => BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}>;
|
||||
}
|
||||
|
||||
const buildStoredAsConstructor = <SO_FAR>(soFar: SO_FAR) => (
|
||||
"storedAs" in soFar ? {} : {
|
||||
storedAsJsonEncodedRedisString: () =>
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as
|
||||
BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}>,
|
||||
storedAsRedisHash: () =>
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as
|
||||
BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}>,
|
||||
}
|
||||
);
|
||||
|
||||
type IdentifierFieldConstructor<SO_FAR> =
|
||||
SO_FAR extends {identifier: any} ? {} :
|
||||
SO_FAR extends {record: any} ? {
|
||||
identifier: <TYPE extends Partial<SO_FAR["record"]>>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & {identifier: TYPE}>
|
||||
} : {}
|
||||
|
||||
const buildIdentifierFieldConstructor = <SO_FAR>(soFar: SO_FAR) => (
|
||||
"identifier" in soFar || (!("record" in soFar)) ? {} : {
|
||||
identifier: <TYPE>(instance: TYPE = undefined) =>
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType<SO_FAR & {identifier: TYPE}>
|
||||
}
|
||||
);
|
||||
|
||||
type RecordFieldConstructor<SO_FAR> =
|
||||
SO_FAR extends {record: any} ? {} : {
|
||||
record: <TYPE>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & {record: TYPE}>
|
||||
}
|
||||
|
||||
const buildRecordFieldConstructor = <SO_FAR>(soFar: SO_FAR) => (
|
||||
"record" in soFar ? {} : {
|
||||
record: <TYPE>(instance: TYPE = undefined) =>
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType<SO_FAR & {record: TYPE}>
|
||||
}
|
||||
);
|
||||
|
||||
type MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> =
|
||||
SO_FAR extends {maxMsToWaitBeforePublishing: any} ? {} : {
|
||||
maxMsToWaitBeforePublishing: (t: number) => BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}>,
|
||||
neverDelayPublishing: () => BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}>,
|
||||
}
|
||||
|
||||
const buildMaxMsToWaitBeforePublishingFieldConstructor = <SO_FAR>(soFar: SO_FAR): MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> => (
|
||||
"maxMsToWaitBeforePublishing" in soFar ? {} : {
|
||||
maxMsToWaitBeforePublishing: (instance: number = 0) =>
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}>,
|
||||
neverDelayPublishing: () =>
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}>,
|
||||
}
|
||||
) as MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR>;
|
||||
|
||||
type TypeConstructor<SO_FAR> =
|
||||
SO_FAR extends {identifier: any, record: any, maxMsToWaitBeforePublishing: number, storedAs: PubSubRecordIsStoredInRedisAsA} ? {
|
||||
type: SO_FAR,
|
||||
fields: Set<keyof SO_FAR>,
|
||||
hasField: (fieldName: string | number | symbol) => fieldName is keyof SO_FAR
|
||||
} : {}
|
||||
|
||||
const buildType = <SO_FAR>(soFar: SO_FAR) => (
|
||||
"identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar && "PubSubRecordIsStoredInRedisAsA" in soFar ? {} : {
|
||||
type: soFar,
|
||||
fields: () => new Set(Object.keys(soFar) as (keyof SO_FAR)[]),
|
||||
hasField: (fieldName: string | number | symbol) => fieldName in soFar
|
||||
}
|
||||
);
|
||||
|
||||
type BuildPubSubRecordType<SO_FAR> =
|
||||
NameFieldConstructor<SO_FAR> &
|
||||
IdentifierFieldConstructor<SO_FAR> &
|
||||
RecordFieldConstructor<SO_FAR> &
|
||||
StoredAsConstructor<SO_FAR> & // infinite loop goes away when you comment out this line
|
||||
MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> &
|
||||
TypeConstructor<SO_FAR>
|
||||
|
||||
const buildPubSubRecordType = <SO_FAR>(soFar: SO_FAR) => Object.assign(
|
||||
{},
|
||||
buildNameFieldConstructor(soFar),
|
||||
buildIdentifierFieldConstructor(soFar),
|
||||
buildRecordFieldConstructor(soFar),
|
||||
buildStoredAsConstructor(soFar),
|
||||
buildMaxMsToWaitBeforePublishingFieldConstructor(soFar),
|
||||
buildType(soFar)
|
||||
) as BuildPubSubRecordType<SO_FAR>;
|
||||
const PubSubRecordType = buildPubSubRecordType({});
|
||||
|
||||
//// [conditionalTypeDoesntSpinForever.js]
|
||||
// A *self-contained* demonstration of the problem follows...
|
||||
// Test this by running `tsc --target es6` on the command-line, rather than through another build tool such as Gulp, Webpack, etc.
|
||||
export var PubSubRecordIsStoredInRedisAsA;
|
||||
(function (PubSubRecordIsStoredInRedisAsA) {
|
||||
PubSubRecordIsStoredInRedisAsA["redisHash"] = "redisHash";
|
||||
PubSubRecordIsStoredInRedisAsA["jsonEncodedRedisString"] = "jsonEncodedRedisString";
|
||||
})(PubSubRecordIsStoredInRedisAsA || (PubSubRecordIsStoredInRedisAsA = {}));
|
||||
const buildNameFieldConstructor = (soFar) => ("name" in soFar ? {} : {
|
||||
name: (instance = undefined) => buildPubSubRecordType(Object.assign({}, soFar, { name: instance }))
|
||||
});
|
||||
const buildStoredAsConstructor = (soFar) => ("storedAs" in soFar ? {} : {
|
||||
storedAsJsonEncodedRedisString: () => buildPubSubRecordType(Object.assign({}, soFar, { storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString })),
|
||||
storedAsRedisHash: () => buildPubSubRecordType(Object.assign({}, soFar, { storedAs: PubSubRecordIsStoredInRedisAsA.redisHash })),
|
||||
});
|
||||
const buildIdentifierFieldConstructor = (soFar) => ("identifier" in soFar || (!("record" in soFar)) ? {} : {
|
||||
identifier: (instance = undefined) => buildPubSubRecordType(Object.assign({}, soFar, { identifier: instance }))
|
||||
});
|
||||
const buildRecordFieldConstructor = (soFar) => ("record" in soFar ? {} : {
|
||||
record: (instance = undefined) => buildPubSubRecordType(Object.assign({}, soFar, { record: instance }))
|
||||
});
|
||||
const buildMaxMsToWaitBeforePublishingFieldConstructor = (soFar) => ("maxMsToWaitBeforePublishing" in soFar ? {} : {
|
||||
maxMsToWaitBeforePublishing: (instance = 0) => buildPubSubRecordType(Object.assign({}, soFar, { maxMsToWaitBeforePublishing: instance })),
|
||||
neverDelayPublishing: () => buildPubSubRecordType(Object.assign({}, soFar, { maxMsToWaitBeforePublishing: 0 })),
|
||||
});
|
||||
const buildType = (soFar) => ("identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar && "PubSubRecordIsStoredInRedisAsA" in soFar ? {} : {
|
||||
type: soFar,
|
||||
fields: () => new Set(Object.keys(soFar)),
|
||||
hasField: (fieldName) => fieldName in soFar
|
||||
});
|
||||
const buildPubSubRecordType = (soFar) => Object.assign({}, buildNameFieldConstructor(soFar), buildIdentifierFieldConstructor(soFar), buildRecordFieldConstructor(soFar), buildStoredAsConstructor(soFar), buildMaxMsToWaitBeforePublishingFieldConstructor(soFar), buildType(soFar));
|
||||
const PubSubRecordType = buildPubSubRecordType({});
|
||||
@ -0,0 +1,489 @@
|
||||
=== tests/cases/compiler/conditionalTypeDoesntSpinForever.ts ===
|
||||
// A *self-contained* demonstration of the problem follows...
|
||||
// Test this by running `tsc --target es6` on the command-line, rather than through another build tool such as Gulp, Webpack, etc.
|
||||
|
||||
export enum PubSubRecordIsStoredInRedisAsA {
|
||||
>PubSubRecordIsStoredInRedisAsA : Symbol(PubSubRecordIsStoredInRedisAsA, Decl(conditionalTypeDoesntSpinForever.ts, 0, 0))
|
||||
|
||||
redisHash = "redisHash",
|
||||
>redisHash : Symbol(PubSubRecordIsStoredInRedisAsA.redisHash, Decl(conditionalTypeDoesntSpinForever.ts, 3, 44))
|
||||
|
||||
jsonEncodedRedisString = "jsonEncodedRedisString"
|
||||
>jsonEncodedRedisString : Symbol(PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString, Decl(conditionalTypeDoesntSpinForever.ts, 4, 28))
|
||||
}
|
||||
|
||||
export interface PubSubRecord<NAME extends string, RECORD, IDENTIFIER extends Partial<RECORD>> {
|
||||
>PubSubRecord : Symbol(PubSubRecord, Decl(conditionalTypeDoesntSpinForever.ts, 6, 3))
|
||||
>NAME : Symbol(NAME, Decl(conditionalTypeDoesntSpinForever.ts, 8, 32))
|
||||
>RECORD : Symbol(RECORD, Decl(conditionalTypeDoesntSpinForever.ts, 8, 52))
|
||||
>IDENTIFIER : Symbol(IDENTIFIER, Decl(conditionalTypeDoesntSpinForever.ts, 8, 60))
|
||||
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
|
||||
>RECORD : Symbol(RECORD, Decl(conditionalTypeDoesntSpinForever.ts, 8, 52))
|
||||
|
||||
name: NAME;
|
||||
>name : Symbol(PubSubRecord.name, Decl(conditionalTypeDoesntSpinForever.ts, 8, 98))
|
||||
>NAME : Symbol(NAME, Decl(conditionalTypeDoesntSpinForever.ts, 8, 32))
|
||||
|
||||
record: RECORD;
|
||||
>record : Symbol(PubSubRecord.record, Decl(conditionalTypeDoesntSpinForever.ts, 9, 15))
|
||||
>RECORD : Symbol(RECORD, Decl(conditionalTypeDoesntSpinForever.ts, 8, 52))
|
||||
|
||||
identifier: IDENTIFIER;
|
||||
>identifier : Symbol(PubSubRecord.identifier, Decl(conditionalTypeDoesntSpinForever.ts, 10, 19))
|
||||
>IDENTIFIER : Symbol(IDENTIFIER, Decl(conditionalTypeDoesntSpinForever.ts, 8, 60))
|
||||
|
||||
storedAs: PubSubRecordIsStoredInRedisAsA;
|
||||
>storedAs : Symbol(PubSubRecord.storedAs, Decl(conditionalTypeDoesntSpinForever.ts, 11, 27))
|
||||
>PubSubRecordIsStoredInRedisAsA : Symbol(PubSubRecordIsStoredInRedisAsA, Decl(conditionalTypeDoesntSpinForever.ts, 0, 0))
|
||||
|
||||
maxMsToWaitBeforePublishing: number;
|
||||
>maxMsToWaitBeforePublishing : Symbol(PubSubRecord.maxMsToWaitBeforePublishing, Decl(conditionalTypeDoesntSpinForever.ts, 12, 45))
|
||||
}
|
||||
|
||||
type NameFieldConstructor<SO_FAR> =
|
||||
>NameFieldConstructor : Symbol(NameFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 14, 3))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 16, 28))
|
||||
|
||||
SO_FAR extends {name: any} ? {} : {
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 16, 28))
|
||||
>name : Symbol(name, Decl(conditionalTypeDoesntSpinForever.ts, 17, 20))
|
||||
|
||||
name: <TYPE>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & {name: TYPE}>
|
||||
>name : Symbol(name, Decl(conditionalTypeDoesntSpinForever.ts, 17, 39))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 18, 13))
|
||||
>t : Symbol(t, Decl(conditionalTypeDoesntSpinForever.ts, 18, 19))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 18, 13))
|
||||
>BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 16, 28))
|
||||
>name : Symbol(name, Decl(conditionalTypeDoesntSpinForever.ts, 18, 64))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 18, 13))
|
||||
}
|
||||
|
||||
const buildNameFieldConstructor = <SO_FAR>(soFar: SO_FAR) => (
|
||||
>buildNameFieldConstructor : Symbol(buildNameFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 21, 7))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 21, 37))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 21, 45))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 21, 37))
|
||||
|
||||
"name" in soFar ? {} : {
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 21, 45))
|
||||
|
||||
name: <TYPE>(instance: TYPE = undefined) =>
|
||||
>name : Symbol(name, Decl(conditionalTypeDoesntSpinForever.ts, 22, 28))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 23, 13))
|
||||
>instance : Symbol(instance, Decl(conditionalTypeDoesntSpinForever.ts, 23, 19))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 23, 13))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType<SO_FAR & {name: TYPE}>
|
||||
>buildPubSubRecordType : Symbol(buildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 108, 7))
|
||||
>Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 21, 45))
|
||||
>name : Symbol(name, Decl(conditionalTypeDoesntSpinForever.ts, 24, 56))
|
||||
>instance : Symbol(instance, Decl(conditionalTypeDoesntSpinForever.ts, 23, 19))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 23, 13))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 21, 37))
|
||||
>name : Symbol(name, Decl(conditionalTypeDoesntSpinForever.ts, 24, 94))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 23, 13))
|
||||
>BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 21, 37))
|
||||
>name : Symbol(name, Decl(conditionalTypeDoesntSpinForever.ts, 24, 142))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 23, 13))
|
||||
}
|
||||
);
|
||||
|
||||
type StoredAsConstructor<SO_FAR> =
|
||||
>StoredAsConstructor : Symbol(StoredAsConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 26, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 28, 27))
|
||||
|
||||
SO_FAR extends {storedAs: any} ? {} : {
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 28, 27))
|
||||
>storedAs : Symbol(storedAs, Decl(conditionalTypeDoesntSpinForever.ts, 29, 20))
|
||||
|
||||
storedAsJsonEncodedRedisString: () => BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}>;
|
||||
>storedAsJsonEncodedRedisString : Symbol(storedAsJsonEncodedRedisString, Decl(conditionalTypeDoesntSpinForever.ts, 29, 43))
|
||||
>BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 28, 27))
|
||||
>storedAs : Symbol(storedAs, Decl(conditionalTypeDoesntSpinForever.ts, 30, 76))
|
||||
>PubSubRecordIsStoredInRedisAsA : Symbol(PubSubRecordIsStoredInRedisAsA, Decl(conditionalTypeDoesntSpinForever.ts, 0, 0))
|
||||
>jsonEncodedRedisString : Symbol(PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString, Decl(conditionalTypeDoesntSpinForever.ts, 4, 28))
|
||||
|
||||
storedRedisHash: () => BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}>;
|
||||
>storedRedisHash : Symbol(storedRedisHash, Decl(conditionalTypeDoesntSpinForever.ts, 30, 142))
|
||||
>BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 28, 27))
|
||||
>storedAs : Symbol(storedAs, Decl(conditionalTypeDoesntSpinForever.ts, 31, 61))
|
||||
>PubSubRecordIsStoredInRedisAsA : Symbol(PubSubRecordIsStoredInRedisAsA, Decl(conditionalTypeDoesntSpinForever.ts, 0, 0))
|
||||
>redisHash : Symbol(PubSubRecordIsStoredInRedisAsA.redisHash, Decl(conditionalTypeDoesntSpinForever.ts, 3, 44))
|
||||
}
|
||||
|
||||
const buildStoredAsConstructor = <SO_FAR>(soFar: SO_FAR) => (
|
||||
>buildStoredAsConstructor : Symbol(buildStoredAsConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 34, 7))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 34, 36))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 34, 44))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 34, 36))
|
||||
|
||||
"storedAs" in soFar ? {} : {
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 34, 44))
|
||||
|
||||
storedAsJsonEncodedRedisString: () =>
|
||||
>storedAsJsonEncodedRedisString : Symbol(storedAsJsonEncodedRedisString, Decl(conditionalTypeDoesntSpinForever.ts, 35, 32))
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as
|
||||
>buildPubSubRecordType : Symbol(buildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 108, 7))
|
||||
>Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 34, 44))
|
||||
>storedAs : Symbol(storedAs, Decl(conditionalTypeDoesntSpinForever.ts, 37, 56))
|
||||
>PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString : Symbol(PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString, Decl(conditionalTypeDoesntSpinForever.ts, 4, 28))
|
||||
>PubSubRecordIsStoredInRedisAsA : Symbol(PubSubRecordIsStoredInRedisAsA, Decl(conditionalTypeDoesntSpinForever.ts, 0, 0))
|
||||
>jsonEncodedRedisString : Symbol(PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString, Decl(conditionalTypeDoesntSpinForever.ts, 4, 28))
|
||||
|
||||
BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}>,
|
||||
>BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 34, 36))
|
||||
>storedAs : Symbol(storedAs, Decl(conditionalTypeDoesntSpinForever.ts, 38, 42))
|
||||
>PubSubRecordIsStoredInRedisAsA : Symbol(PubSubRecordIsStoredInRedisAsA, Decl(conditionalTypeDoesntSpinForever.ts, 0, 0))
|
||||
>jsonEncodedRedisString : Symbol(PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString, Decl(conditionalTypeDoesntSpinForever.ts, 4, 28))
|
||||
|
||||
storedAsRedisHash: () =>
|
||||
>storedAsRedisHash : Symbol(storedAsRedisHash, Decl(conditionalTypeDoesntSpinForever.ts, 38, 108))
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as
|
||||
>buildPubSubRecordType : Symbol(buildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 108, 7))
|
||||
>Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 34, 44))
|
||||
>storedAs : Symbol(storedAs, Decl(conditionalTypeDoesntSpinForever.ts, 40, 56))
|
||||
>PubSubRecordIsStoredInRedisAsA.redisHash : Symbol(PubSubRecordIsStoredInRedisAsA.redisHash, Decl(conditionalTypeDoesntSpinForever.ts, 3, 44))
|
||||
>PubSubRecordIsStoredInRedisAsA : Symbol(PubSubRecordIsStoredInRedisAsA, Decl(conditionalTypeDoesntSpinForever.ts, 0, 0))
|
||||
>redisHash : Symbol(PubSubRecordIsStoredInRedisAsA.redisHash, Decl(conditionalTypeDoesntSpinForever.ts, 3, 44))
|
||||
|
||||
BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}>,
|
||||
>BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 34, 36))
|
||||
>storedAs : Symbol(storedAs, Decl(conditionalTypeDoesntSpinForever.ts, 41, 42))
|
||||
>PubSubRecordIsStoredInRedisAsA : Symbol(PubSubRecordIsStoredInRedisAsA, Decl(conditionalTypeDoesntSpinForever.ts, 0, 0))
|
||||
>redisHash : Symbol(PubSubRecordIsStoredInRedisAsA.redisHash, Decl(conditionalTypeDoesntSpinForever.ts, 3, 44))
|
||||
}
|
||||
);
|
||||
|
||||
type IdentifierFieldConstructor<SO_FAR> =
|
||||
>IdentifierFieldConstructor : Symbol(IdentifierFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 43, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 45, 34))
|
||||
|
||||
SO_FAR extends {identifier: any} ? {} :
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 45, 34))
|
||||
>identifier : Symbol(identifier, Decl(conditionalTypeDoesntSpinForever.ts, 46, 20))
|
||||
|
||||
SO_FAR extends {record: any} ? {
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 45, 34))
|
||||
>record : Symbol(record, Decl(conditionalTypeDoesntSpinForever.ts, 47, 20))
|
||||
|
||||
identifier: <TYPE extends Partial<SO_FAR["record"]>>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & {identifier: TYPE}>
|
||||
>identifier : Symbol(identifier, Decl(conditionalTypeDoesntSpinForever.ts, 47, 36))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 48, 19))
|
||||
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 45, 34))
|
||||
>t : Symbol(t, Decl(conditionalTypeDoesntSpinForever.ts, 48, 59))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 48, 19))
|
||||
>BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 45, 34))
|
||||
>identifier : Symbol(identifier, Decl(conditionalTypeDoesntSpinForever.ts, 48, 104))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 48, 19))
|
||||
|
||||
} : {}
|
||||
|
||||
const buildIdentifierFieldConstructor = <SO_FAR>(soFar: SO_FAR) => (
|
||||
>buildIdentifierFieldConstructor : Symbol(buildIdentifierFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 51, 7))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 51, 43))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 51, 51))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 51, 43))
|
||||
|
||||
"identifier" in soFar || (!("record" in soFar)) ? {} : {
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 51, 51))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 51, 51))
|
||||
|
||||
identifier: <TYPE>(instance: TYPE = undefined) =>
|
||||
>identifier : Symbol(identifier, Decl(conditionalTypeDoesntSpinForever.ts, 52, 60))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 53, 19))
|
||||
>instance : Symbol(instance, Decl(conditionalTypeDoesntSpinForever.ts, 53, 25))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 53, 19))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType<SO_FAR & {identifier: TYPE}>
|
||||
>buildPubSubRecordType : Symbol(buildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 108, 7))
|
||||
>Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 51, 51))
|
||||
>identifier : Symbol(identifier, Decl(conditionalTypeDoesntSpinForever.ts, 54, 56))
|
||||
>instance : Symbol(instance, Decl(conditionalTypeDoesntSpinForever.ts, 53, 25))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 53, 19))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 51, 43))
|
||||
>identifier : Symbol(identifier, Decl(conditionalTypeDoesntSpinForever.ts, 54, 100))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 53, 19))
|
||||
>BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 51, 43))
|
||||
>identifier : Symbol(identifier, Decl(conditionalTypeDoesntSpinForever.ts, 54, 154))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 53, 19))
|
||||
}
|
||||
);
|
||||
|
||||
type RecordFieldConstructor<SO_FAR> =
|
||||
>RecordFieldConstructor : Symbol(RecordFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 56, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 58, 30))
|
||||
|
||||
SO_FAR extends {record: any} ? {} : {
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 58, 30))
|
||||
>record : Symbol(record, Decl(conditionalTypeDoesntSpinForever.ts, 59, 20))
|
||||
|
||||
record: <TYPE>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & {record: TYPE}>
|
||||
>record : Symbol(record, Decl(conditionalTypeDoesntSpinForever.ts, 59, 41))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 60, 15))
|
||||
>t : Symbol(t, Decl(conditionalTypeDoesntSpinForever.ts, 60, 21))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 60, 15))
|
||||
>BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 58, 30))
|
||||
>record : Symbol(record, Decl(conditionalTypeDoesntSpinForever.ts, 60, 66))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 60, 15))
|
||||
}
|
||||
|
||||
const buildRecordFieldConstructor = <SO_FAR>(soFar: SO_FAR) => (
|
||||
>buildRecordFieldConstructor : Symbol(buildRecordFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 63, 7))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 63, 39))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 63, 47))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 63, 39))
|
||||
|
||||
"record" in soFar ? {} : {
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 63, 47))
|
||||
|
||||
record: <TYPE>(instance: TYPE = undefined) =>
|
||||
>record : Symbol(record, Decl(conditionalTypeDoesntSpinForever.ts, 64, 30))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 65, 15))
|
||||
>instance : Symbol(instance, Decl(conditionalTypeDoesntSpinForever.ts, 65, 21))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 65, 15))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType<SO_FAR & {record: TYPE}>
|
||||
>buildPubSubRecordType : Symbol(buildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 108, 7))
|
||||
>Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 63, 47))
|
||||
>record : Symbol(record, Decl(conditionalTypeDoesntSpinForever.ts, 66, 56))
|
||||
>instance : Symbol(instance, Decl(conditionalTypeDoesntSpinForever.ts, 65, 21))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 65, 15))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 63, 39))
|
||||
>record : Symbol(record, Decl(conditionalTypeDoesntSpinForever.ts, 66, 96))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 65, 15))
|
||||
>BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 63, 39))
|
||||
>record : Symbol(record, Decl(conditionalTypeDoesntSpinForever.ts, 66, 146))
|
||||
>TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 65, 15))
|
||||
}
|
||||
);
|
||||
|
||||
type MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> =
|
||||
>MaxMsToWaitBeforePublishingFieldConstructor : Symbol(MaxMsToWaitBeforePublishingFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 68, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 70, 51))
|
||||
|
||||
SO_FAR extends {maxMsToWaitBeforePublishing: any} ? {} : {
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 70, 51))
|
||||
>maxMsToWaitBeforePublishing : Symbol(maxMsToWaitBeforePublishing, Decl(conditionalTypeDoesntSpinForever.ts, 71, 20))
|
||||
|
||||
maxMsToWaitBeforePublishing: (t: number) => BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}>,
|
||||
>maxMsToWaitBeforePublishing : Symbol(maxMsToWaitBeforePublishing, Decl(conditionalTypeDoesntSpinForever.ts, 71, 62))
|
||||
>t : Symbol(t, Decl(conditionalTypeDoesntSpinForever.ts, 72, 36))
|
||||
>BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 70, 51))
|
||||
>maxMsToWaitBeforePublishing : Symbol(maxMsToWaitBeforePublishing, Decl(conditionalTypeDoesntSpinForever.ts, 72, 82))
|
||||
|
||||
neverDelayPublishing: () => BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}>,
|
||||
>neverDelayPublishing : Symbol(neverDelayPublishing, Decl(conditionalTypeDoesntSpinForever.ts, 72, 120))
|
||||
>BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 70, 51))
|
||||
>maxMsToWaitBeforePublishing : Symbol(maxMsToWaitBeforePublishing, Decl(conditionalTypeDoesntSpinForever.ts, 73, 66))
|
||||
}
|
||||
|
||||
const buildMaxMsToWaitBeforePublishingFieldConstructor = <SO_FAR>(soFar: SO_FAR): MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> => (
|
||||
>buildMaxMsToWaitBeforePublishingFieldConstructor : Symbol(buildMaxMsToWaitBeforePublishingFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 76, 7))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 76, 60))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 76, 68))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 76, 60))
|
||||
>MaxMsToWaitBeforePublishingFieldConstructor : Symbol(MaxMsToWaitBeforePublishingFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 68, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 76, 60))
|
||||
|
||||
"maxMsToWaitBeforePublishing" in soFar ? {} : {
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 76, 68))
|
||||
|
||||
maxMsToWaitBeforePublishing: (instance: number = 0) =>
|
||||
>maxMsToWaitBeforePublishing : Symbol(maxMsToWaitBeforePublishing, Decl(conditionalTypeDoesntSpinForever.ts, 77, 51))
|
||||
>instance : Symbol(instance, Decl(conditionalTypeDoesntSpinForever.ts, 78, 36))
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}>,
|
||||
>buildPubSubRecordType : Symbol(buildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 108, 7))
|
||||
>Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 76, 68))
|
||||
>maxMsToWaitBeforePublishing : Symbol(maxMsToWaitBeforePublishing, Decl(conditionalTypeDoesntSpinForever.ts, 79, 56))
|
||||
>instance : Symbol(instance, Decl(conditionalTypeDoesntSpinForever.ts, 78, 36))
|
||||
>BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 76, 60))
|
||||
>maxMsToWaitBeforePublishing : Symbol(maxMsToWaitBeforePublishing, Decl(conditionalTypeDoesntSpinForever.ts, 79, 132))
|
||||
|
||||
neverDelayPublishing: () =>
|
||||
>neverDelayPublishing : Symbol(neverDelayPublishing, Decl(conditionalTypeDoesntSpinForever.ts, 79, 170))
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}>,
|
||||
>buildPubSubRecordType : Symbol(buildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 108, 7))
|
||||
>Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 76, 68))
|
||||
>maxMsToWaitBeforePublishing : Symbol(maxMsToWaitBeforePublishing, Decl(conditionalTypeDoesntSpinForever.ts, 81, 56))
|
||||
>BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 76, 60))
|
||||
>maxMsToWaitBeforePublishing : Symbol(maxMsToWaitBeforePublishing, Decl(conditionalTypeDoesntSpinForever.ts, 81, 125))
|
||||
}
|
||||
) as MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR>;
|
||||
>MaxMsToWaitBeforePublishingFieldConstructor : Symbol(MaxMsToWaitBeforePublishingFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 68, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 76, 60))
|
||||
|
||||
type TypeConstructor<SO_FAR> =
|
||||
>TypeConstructor : Symbol(TypeConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 83, 59))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 85, 23))
|
||||
|
||||
SO_FAR extends {identifier: any, record: any, maxMsToWaitBeforePublishing: number, storedAs: PubSubRecordIsStoredInRedisAsA} ? {
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 85, 23))
|
||||
>identifier : Symbol(identifier, Decl(conditionalTypeDoesntSpinForever.ts, 86, 20))
|
||||
>record : Symbol(record, Decl(conditionalTypeDoesntSpinForever.ts, 86, 36))
|
||||
>maxMsToWaitBeforePublishing : Symbol(maxMsToWaitBeforePublishing, Decl(conditionalTypeDoesntSpinForever.ts, 86, 49))
|
||||
>storedAs : Symbol(storedAs, Decl(conditionalTypeDoesntSpinForever.ts, 86, 86))
|
||||
>PubSubRecordIsStoredInRedisAsA : Symbol(PubSubRecordIsStoredInRedisAsA, Decl(conditionalTypeDoesntSpinForever.ts, 0, 0))
|
||||
|
||||
type: SO_FAR,
|
||||
>type : Symbol(type, Decl(conditionalTypeDoesntSpinForever.ts, 86, 132))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 85, 23))
|
||||
|
||||
fields: Set<keyof SO_FAR>,
|
||||
>fields : Symbol(fields, Decl(conditionalTypeDoesntSpinForever.ts, 87, 19))
|
||||
>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 85, 23))
|
||||
|
||||
hasField: (fieldName: string | number | symbol) => fieldName is keyof SO_FAR
|
||||
>hasField : Symbol(hasField, Decl(conditionalTypeDoesntSpinForever.ts, 88, 32))
|
||||
>fieldName : Symbol(fieldName, Decl(conditionalTypeDoesntSpinForever.ts, 89, 17))
|
||||
>fieldName : Symbol(fieldName, Decl(conditionalTypeDoesntSpinForever.ts, 89, 17))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 85, 23))
|
||||
|
||||
} : {}
|
||||
|
||||
const buildType = <SO_FAR>(soFar: SO_FAR) => (
|
||||
>buildType : Symbol(buildType, Decl(conditionalTypeDoesntSpinForever.ts, 92, 7))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 92, 21))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 29))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 92, 21))
|
||||
|
||||
"identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar && "PubSubRecordIsStoredInRedisAsA" in soFar ? {} : {
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 29))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 29))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 29))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 29))
|
||||
|
||||
type: soFar,
|
||||
>type : Symbol(type, Decl(conditionalTypeDoesntSpinForever.ts, 93, 142))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 29))
|
||||
|
||||
fields: () => new Set(Object.keys(soFar) as (keyof SO_FAR)[]),
|
||||
>fields : Symbol(fields, Decl(conditionalTypeDoesntSpinForever.ts, 94, 18))
|
||||
>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>Object.keys : Symbol(ObjectConstructor.keys, Decl(lib.es5.d.ts, --, --))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>keys : Symbol(ObjectConstructor.keys, Decl(lib.es5.d.ts, --, --))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 29))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 92, 21))
|
||||
|
||||
hasField: (fieldName: string | number | symbol) => fieldName in soFar
|
||||
>hasField : Symbol(hasField, Decl(conditionalTypeDoesntSpinForever.ts, 95, 68))
|
||||
>fieldName : Symbol(fieldName, Decl(conditionalTypeDoesntSpinForever.ts, 96, 17))
|
||||
>fieldName : Symbol(fieldName, Decl(conditionalTypeDoesntSpinForever.ts, 96, 17))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 29))
|
||||
}
|
||||
);
|
||||
|
||||
type BuildPubSubRecordType<SO_FAR> =
|
||||
>BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 100, 29))
|
||||
|
||||
NameFieldConstructor<SO_FAR> &
|
||||
>NameFieldConstructor : Symbol(NameFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 14, 3))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 100, 29))
|
||||
|
||||
IdentifierFieldConstructor<SO_FAR> &
|
||||
>IdentifierFieldConstructor : Symbol(IdentifierFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 43, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 100, 29))
|
||||
|
||||
RecordFieldConstructor<SO_FAR> &
|
||||
>RecordFieldConstructor : Symbol(RecordFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 56, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 100, 29))
|
||||
|
||||
StoredAsConstructor<SO_FAR> & // infinite loop goes away when you comment out this line
|
||||
>StoredAsConstructor : Symbol(StoredAsConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 26, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 100, 29))
|
||||
|
||||
MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> &
|
||||
>MaxMsToWaitBeforePublishingFieldConstructor : Symbol(MaxMsToWaitBeforePublishingFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 68, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 100, 29))
|
||||
|
||||
TypeConstructor<SO_FAR>
|
||||
>TypeConstructor : Symbol(TypeConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 83, 59))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 100, 29))
|
||||
|
||||
const buildPubSubRecordType = <SO_FAR>(soFar: SO_FAR) => Object.assign(
|
||||
>buildPubSubRecordType : Symbol(buildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 108, 7))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 108, 33))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 41))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 108, 33))
|
||||
>Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
|
||||
{},
|
||||
buildNameFieldConstructor(soFar),
|
||||
>buildNameFieldConstructor : Symbol(buildNameFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 21, 7))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 41))
|
||||
|
||||
buildIdentifierFieldConstructor(soFar),
|
||||
>buildIdentifierFieldConstructor : Symbol(buildIdentifierFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 51, 7))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 41))
|
||||
|
||||
buildRecordFieldConstructor(soFar),
|
||||
>buildRecordFieldConstructor : Symbol(buildRecordFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 63, 7))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 41))
|
||||
|
||||
buildStoredAsConstructor(soFar),
|
||||
>buildStoredAsConstructor : Symbol(buildStoredAsConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 34, 7))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 41))
|
||||
|
||||
buildMaxMsToWaitBeforePublishingFieldConstructor(soFar),
|
||||
>buildMaxMsToWaitBeforePublishingFieldConstructor : Symbol(buildMaxMsToWaitBeforePublishingFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 76, 7))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 41))
|
||||
|
||||
buildType(soFar)
|
||||
>buildType : Symbol(buildType, Decl(conditionalTypeDoesntSpinForever.ts, 92, 7))
|
||||
>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 41))
|
||||
|
||||
) as BuildPubSubRecordType<SO_FAR>;
|
||||
>BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4))
|
||||
>SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 108, 33))
|
||||
|
||||
const PubSubRecordType = buildPubSubRecordType({});
|
||||
>PubSubRecordType : Symbol(PubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 117, 7))
|
||||
>buildPubSubRecordType : Symbol(buildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 108, 7))
|
||||
|
||||
487
tests/baselines/reference/conditionalTypeDoesntSpinForever.types
Normal file
487
tests/baselines/reference/conditionalTypeDoesntSpinForever.types
Normal file
@ -0,0 +1,487 @@
|
||||
=== tests/cases/compiler/conditionalTypeDoesntSpinForever.ts ===
|
||||
// A *self-contained* demonstration of the problem follows...
|
||||
// Test this by running `tsc --target es6` on the command-line, rather than through another build tool such as Gulp, Webpack, etc.
|
||||
|
||||
export enum PubSubRecordIsStoredInRedisAsA {
|
||||
>PubSubRecordIsStoredInRedisAsA : PubSubRecordIsStoredInRedisAsA
|
||||
|
||||
redisHash = "redisHash",
|
||||
>redisHash : PubSubRecordIsStoredInRedisAsA.redisHash
|
||||
>"redisHash" : "redisHash"
|
||||
|
||||
jsonEncodedRedisString = "jsonEncodedRedisString"
|
||||
>jsonEncodedRedisString : PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString
|
||||
>"jsonEncodedRedisString" : "jsonEncodedRedisString"
|
||||
}
|
||||
|
||||
export interface PubSubRecord<NAME extends string, RECORD, IDENTIFIER extends Partial<RECORD>> {
|
||||
name: NAME;
|
||||
>name : NAME
|
||||
|
||||
record: RECORD;
|
||||
>record : RECORD
|
||||
|
||||
identifier: IDENTIFIER;
|
||||
>identifier : IDENTIFIER
|
||||
|
||||
storedAs: PubSubRecordIsStoredInRedisAsA;
|
||||
>storedAs : PubSubRecordIsStoredInRedisAsA
|
||||
|
||||
maxMsToWaitBeforePublishing: number;
|
||||
>maxMsToWaitBeforePublishing : number
|
||||
}
|
||||
|
||||
type NameFieldConstructor<SO_FAR> =
|
||||
>NameFieldConstructor : NameFieldConstructor<SO_FAR>
|
||||
|
||||
SO_FAR extends {name: any} ? {} : {
|
||||
>name : any
|
||||
|
||||
name: <TYPE>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & {name: TYPE}>
|
||||
>name : <TYPE>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & { name: TYPE; }>
|
||||
>t : TYPE
|
||||
>name : TYPE
|
||||
}
|
||||
|
||||
const buildNameFieldConstructor = <SO_FAR>(soFar: SO_FAR) => (
|
||||
>buildNameFieldConstructor : <SO_FAR>(soFar: SO_FAR) => { name?: undefined; } | { name: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { name: TYPE; }>; }
|
||||
><SO_FAR>(soFar: SO_FAR) => ( "name" in soFar ? {} : { name: <TYPE>(instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType<SO_FAR & {name: TYPE}> } ) : <SO_FAR>(soFar: SO_FAR) => { name?: undefined; } | { name: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { name: TYPE; }>; }
|
||||
>soFar : SO_FAR
|
||||
>( "name" in soFar ? {} : { name: <TYPE>(instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType<SO_FAR & {name: TYPE}> } ) : {} | { name: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { name: TYPE; }>; }
|
||||
|
||||
"name" in soFar ? {} : {
|
||||
>"name" in soFar ? {} : { name: <TYPE>(instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType<SO_FAR & {name: TYPE}> } : {} | { name: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { name: TYPE; }>; }
|
||||
>"name" in soFar : boolean
|
||||
>"name" : "name"
|
||||
>soFar : SO_FAR
|
||||
>{} : {}
|
||||
>{ name: <TYPE>(instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType<SO_FAR & {name: TYPE}> } : { name: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { name: TYPE; }>; }
|
||||
|
||||
name: <TYPE>(instance: TYPE = undefined) =>
|
||||
>name : <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { name: TYPE; }>
|
||||
><TYPE>(instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType<SO_FAR & {name: TYPE}> : <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { name: TYPE; }>
|
||||
>instance : TYPE
|
||||
>undefined : undefined
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType<SO_FAR & {name: TYPE}>
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType<SO_FAR & {name: TYPE}> : BuildPubSubRecordType<SO_FAR & { name: TYPE; }>
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) : BuildPubSubRecordType<SO_FAR & { name: TYPE; }>
|
||||
>buildPubSubRecordType : <SO_FAR>(soFar: SO_FAR) => BuildPubSubRecordType<SO_FAR>
|
||||
>Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE} : SO_FAR & { name: TYPE; }
|
||||
>Object.assign({}, soFar, {name: instance as TYPE}) : SO_FAR & { name: TYPE; }
|
||||
>Object.assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>Object : ObjectConstructor
|
||||
>assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>{} : {}
|
||||
>soFar : SO_FAR
|
||||
>{name: instance as TYPE} : { name: TYPE; }
|
||||
>name : TYPE
|
||||
>instance as TYPE : TYPE
|
||||
>instance : TYPE
|
||||
>name : TYPE
|
||||
>name : TYPE
|
||||
}
|
||||
);
|
||||
|
||||
type StoredAsConstructor<SO_FAR> =
|
||||
>StoredAsConstructor : StoredAsConstructor<SO_FAR>
|
||||
|
||||
SO_FAR extends {storedAs: any} ? {} : {
|
||||
>storedAs : any
|
||||
|
||||
storedAsJsonEncodedRedisString: () => BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}>;
|
||||
>storedAsJsonEncodedRedisString : () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString; }>
|
||||
>storedAs : PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString
|
||||
>PubSubRecordIsStoredInRedisAsA : any
|
||||
|
||||
storedRedisHash: () => BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}>;
|
||||
>storedRedisHash : () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.redisHash; }>
|
||||
>storedAs : PubSubRecordIsStoredInRedisAsA.redisHash
|
||||
>PubSubRecordIsStoredInRedisAsA : any
|
||||
}
|
||||
|
||||
const buildStoredAsConstructor = <SO_FAR>(soFar: SO_FAR) => (
|
||||
>buildStoredAsConstructor : <SO_FAR>(soFar: SO_FAR) => { storedAsJsonEncodedRedisString?: undefined; storedAsRedisHash?: undefined; } | { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString; }>; storedAsRedisHash: () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.redisHash; }>; }
|
||||
><SO_FAR>(soFar: SO_FAR) => ( "storedAs" in soFar ? {} : { storedAsJsonEncodedRedisString: () => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}>, storedAsRedisHash: () => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}>, } ) : <SO_FAR>(soFar: SO_FAR) => { storedAsJsonEncodedRedisString?: undefined; storedAsRedisHash?: undefined; } | { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString; }>; storedAsRedisHash: () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.redisHash; }>; }
|
||||
>soFar : SO_FAR
|
||||
>( "storedAs" in soFar ? {} : { storedAsJsonEncodedRedisString: () => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}>, storedAsRedisHash: () => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}>, } ) : {} | { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString; }>; storedAsRedisHash: () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.redisHash; }>; }
|
||||
|
||||
"storedAs" in soFar ? {} : {
|
||||
>"storedAs" in soFar ? {} : { storedAsJsonEncodedRedisString: () => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}>, storedAsRedisHash: () => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}>, } : {} | { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString; }>; storedAsRedisHash: () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.redisHash; }>; }
|
||||
>"storedAs" in soFar : boolean
|
||||
>"storedAs" : "storedAs"
|
||||
>soFar : SO_FAR
|
||||
>{} : {}
|
||||
>{ storedAsJsonEncodedRedisString: () => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}>, storedAsRedisHash: () => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}>, } : { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString; }>; storedAsRedisHash: () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.redisHash; }>; }
|
||||
|
||||
storedAsJsonEncodedRedisString: () =>
|
||||
>storedAsJsonEncodedRedisString : () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString; }>
|
||||
>() => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}> : () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString; }>
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}> : BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString; }>
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) : BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA; }>
|
||||
>buildPubSubRecordType : <SO_FAR>(soFar: SO_FAR) => BuildPubSubRecordType<SO_FAR>
|
||||
>Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}) : SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA; }
|
||||
>Object.assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>Object : ObjectConstructor
|
||||
>assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>{} : {}
|
||||
>soFar : SO_FAR
|
||||
>{storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString} : { storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString; }
|
||||
>storedAs : PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString
|
||||
>PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString : PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString
|
||||
>PubSubRecordIsStoredInRedisAsA : typeof PubSubRecordIsStoredInRedisAsA
|
||||
>jsonEncodedRedisString : PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString
|
||||
|
||||
BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}>,
|
||||
>storedAs : PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString
|
||||
>PubSubRecordIsStoredInRedisAsA : any
|
||||
|
||||
storedAsRedisHash: () =>
|
||||
>storedAsRedisHash : () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.redisHash; }>
|
||||
>() => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}> : () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.redisHash; }>
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}> : BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.redisHash; }>
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) : BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA; }>
|
||||
>buildPubSubRecordType : <SO_FAR>(soFar: SO_FAR) => BuildPubSubRecordType<SO_FAR>
|
||||
>Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}) : SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA; }
|
||||
>Object.assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>Object : ObjectConstructor
|
||||
>assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>{} : {}
|
||||
>soFar : SO_FAR
|
||||
>{storedAs: PubSubRecordIsStoredInRedisAsA.redisHash} : { storedAs: PubSubRecordIsStoredInRedisAsA.redisHash; }
|
||||
>storedAs : PubSubRecordIsStoredInRedisAsA.redisHash
|
||||
>PubSubRecordIsStoredInRedisAsA.redisHash : PubSubRecordIsStoredInRedisAsA.redisHash
|
||||
>PubSubRecordIsStoredInRedisAsA : typeof PubSubRecordIsStoredInRedisAsA
|
||||
>redisHash : PubSubRecordIsStoredInRedisAsA.redisHash
|
||||
|
||||
BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}>,
|
||||
>storedAs : PubSubRecordIsStoredInRedisAsA.redisHash
|
||||
>PubSubRecordIsStoredInRedisAsA : any
|
||||
}
|
||||
);
|
||||
|
||||
type IdentifierFieldConstructor<SO_FAR> =
|
||||
>IdentifierFieldConstructor : IdentifierFieldConstructor<SO_FAR>
|
||||
|
||||
SO_FAR extends {identifier: any} ? {} :
|
||||
>identifier : any
|
||||
|
||||
SO_FAR extends {record: any} ? {
|
||||
>record : any
|
||||
|
||||
identifier: <TYPE extends Partial<SO_FAR["record"]>>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & {identifier: TYPE}>
|
||||
>identifier : <TYPE extends Partial<SO_FAR["record"]>>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & { identifier: TYPE; }>
|
||||
>t : TYPE
|
||||
>identifier : TYPE
|
||||
|
||||
} : {}
|
||||
|
||||
const buildIdentifierFieldConstructor = <SO_FAR>(soFar: SO_FAR) => (
|
||||
>buildIdentifierFieldConstructor : <SO_FAR>(soFar: SO_FAR) => { identifier?: undefined; } | { identifier: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { identifier: TYPE; }>; }
|
||||
><SO_FAR>(soFar: SO_FAR) => ( "identifier" in soFar || (!("record" in soFar)) ? {} : { identifier: <TYPE>(instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType<SO_FAR & {identifier: TYPE}> } ) : <SO_FAR>(soFar: SO_FAR) => { identifier?: undefined; } | { identifier: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { identifier: TYPE; }>; }
|
||||
>soFar : SO_FAR
|
||||
>( "identifier" in soFar || (!("record" in soFar)) ? {} : { identifier: <TYPE>(instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType<SO_FAR & {identifier: TYPE}> } ) : {} | { identifier: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { identifier: TYPE; }>; }
|
||||
|
||||
"identifier" in soFar || (!("record" in soFar)) ? {} : {
|
||||
>"identifier" in soFar || (!("record" in soFar)) ? {} : { identifier: <TYPE>(instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType<SO_FAR & {identifier: TYPE}> } : {} | { identifier: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { identifier: TYPE; }>; }
|
||||
>"identifier" in soFar || (!("record" in soFar)) : boolean
|
||||
>"identifier" in soFar : boolean
|
||||
>"identifier" : "identifier"
|
||||
>soFar : SO_FAR
|
||||
>(!("record" in soFar)) : boolean
|
||||
>!("record" in soFar) : boolean
|
||||
>("record" in soFar) : boolean
|
||||
>"record" in soFar : boolean
|
||||
>"record" : "record"
|
||||
>soFar : SO_FAR
|
||||
>{} : {}
|
||||
>{ identifier: <TYPE>(instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType<SO_FAR & {identifier: TYPE}> } : { identifier: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { identifier: TYPE; }>; }
|
||||
|
||||
identifier: <TYPE>(instance: TYPE = undefined) =>
|
||||
>identifier : <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { identifier: TYPE; }>
|
||||
><TYPE>(instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType<SO_FAR & {identifier: TYPE}> : <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { identifier: TYPE; }>
|
||||
>instance : TYPE
|
||||
>undefined : undefined
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType<SO_FAR & {identifier: TYPE}>
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType<SO_FAR & {identifier: TYPE}> : BuildPubSubRecordType<SO_FAR & { identifier: TYPE; }>
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) : BuildPubSubRecordType<SO_FAR & { identifier: TYPE; }>
|
||||
>buildPubSubRecordType : <SO_FAR>(soFar: SO_FAR) => BuildPubSubRecordType<SO_FAR>
|
||||
>Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE} : SO_FAR & { identifier: TYPE; }
|
||||
>Object.assign({}, soFar, {identifier: instance as TYPE}) : SO_FAR & { identifier: TYPE; }
|
||||
>Object.assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>Object : ObjectConstructor
|
||||
>assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>{} : {}
|
||||
>soFar : SO_FAR
|
||||
>{identifier: instance as TYPE} : { identifier: TYPE; }
|
||||
>identifier : TYPE
|
||||
>instance as TYPE : TYPE
|
||||
>instance : TYPE
|
||||
>identifier : TYPE
|
||||
>identifier : TYPE
|
||||
}
|
||||
);
|
||||
|
||||
type RecordFieldConstructor<SO_FAR> =
|
||||
>RecordFieldConstructor : RecordFieldConstructor<SO_FAR>
|
||||
|
||||
SO_FAR extends {record: any} ? {} : {
|
||||
>record : any
|
||||
|
||||
record: <TYPE>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & {record: TYPE}>
|
||||
>record : <TYPE>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & { record: TYPE; }>
|
||||
>t : TYPE
|
||||
>record : TYPE
|
||||
}
|
||||
|
||||
const buildRecordFieldConstructor = <SO_FAR>(soFar: SO_FAR) => (
|
||||
>buildRecordFieldConstructor : <SO_FAR>(soFar: SO_FAR) => { record?: undefined; } | { record: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { record: TYPE; }>; }
|
||||
><SO_FAR>(soFar: SO_FAR) => ( "record" in soFar ? {} : { record: <TYPE>(instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType<SO_FAR & {record: TYPE}> } ) : <SO_FAR>(soFar: SO_FAR) => { record?: undefined; } | { record: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { record: TYPE; }>; }
|
||||
>soFar : SO_FAR
|
||||
>( "record" in soFar ? {} : { record: <TYPE>(instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType<SO_FAR & {record: TYPE}> } ) : {} | { record: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { record: TYPE; }>; }
|
||||
|
||||
"record" in soFar ? {} : {
|
||||
>"record" in soFar ? {} : { record: <TYPE>(instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType<SO_FAR & {record: TYPE}> } : {} | { record: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { record: TYPE; }>; }
|
||||
>"record" in soFar : boolean
|
||||
>"record" : "record"
|
||||
>soFar : SO_FAR
|
||||
>{} : {}
|
||||
>{ record: <TYPE>(instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType<SO_FAR & {record: TYPE}> } : { record: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { record: TYPE; }>; }
|
||||
|
||||
record: <TYPE>(instance: TYPE = undefined) =>
|
||||
>record : <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { record: TYPE; }>
|
||||
><TYPE>(instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType<SO_FAR & {record: TYPE}> : <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { record: TYPE; }>
|
||||
>instance : TYPE
|
||||
>undefined : undefined
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType<SO_FAR & {record: TYPE}>
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType<SO_FAR & {record: TYPE}> : BuildPubSubRecordType<SO_FAR & { record: TYPE; }>
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) : BuildPubSubRecordType<SO_FAR & { record: TYPE; }>
|
||||
>buildPubSubRecordType : <SO_FAR>(soFar: SO_FAR) => BuildPubSubRecordType<SO_FAR>
|
||||
>Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE} : SO_FAR & { record: TYPE; }
|
||||
>Object.assign({}, soFar, {record: instance as TYPE}) : SO_FAR & { record: TYPE; }
|
||||
>Object.assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>Object : ObjectConstructor
|
||||
>assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>{} : {}
|
||||
>soFar : SO_FAR
|
||||
>{record: instance as TYPE} : { record: TYPE; }
|
||||
>record : TYPE
|
||||
>instance as TYPE : TYPE
|
||||
>instance : TYPE
|
||||
>record : TYPE
|
||||
>record : TYPE
|
||||
}
|
||||
);
|
||||
|
||||
type MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> =
|
||||
>MaxMsToWaitBeforePublishingFieldConstructor : MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR>
|
||||
|
||||
SO_FAR extends {maxMsToWaitBeforePublishing: any} ? {} : {
|
||||
>maxMsToWaitBeforePublishing : any
|
||||
|
||||
maxMsToWaitBeforePublishing: (t: number) => BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}>,
|
||||
>maxMsToWaitBeforePublishing : (t: number) => BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: number; }>
|
||||
>t : number
|
||||
>maxMsToWaitBeforePublishing : number
|
||||
|
||||
neverDelayPublishing: () => BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}>,
|
||||
>neverDelayPublishing : () => BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: 0; }>
|
||||
>maxMsToWaitBeforePublishing : 0
|
||||
}
|
||||
|
||||
const buildMaxMsToWaitBeforePublishingFieldConstructor = <SO_FAR>(soFar: SO_FAR): MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> => (
|
||||
>buildMaxMsToWaitBeforePublishingFieldConstructor : <SO_FAR>(soFar: SO_FAR) => MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR>
|
||||
><SO_FAR>(soFar: SO_FAR): MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> => ( "maxMsToWaitBeforePublishing" in soFar ? {} : { maxMsToWaitBeforePublishing: (instance: number = 0) => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}>, neverDelayPublishing: () => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}>, } ) as MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> : <SO_FAR>(soFar: SO_FAR) => MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR>
|
||||
>soFar : SO_FAR
|
||||
>( "maxMsToWaitBeforePublishing" in soFar ? {} : { maxMsToWaitBeforePublishing: (instance: number = 0) => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}>, neverDelayPublishing: () => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}>, } ) as MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> : MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR>
|
||||
>( "maxMsToWaitBeforePublishing" in soFar ? {} : { maxMsToWaitBeforePublishing: (instance: number = 0) => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}>, neverDelayPublishing: () => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}>, } ) : {} | { maxMsToWaitBeforePublishing: (instance?: number) => BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: number; }>; neverDelayPublishing: () => BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: 0; }>; }
|
||||
|
||||
"maxMsToWaitBeforePublishing" in soFar ? {} : {
|
||||
>"maxMsToWaitBeforePublishing" in soFar ? {} : { maxMsToWaitBeforePublishing: (instance: number = 0) => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}>, neverDelayPublishing: () => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}>, } : {} | { maxMsToWaitBeforePublishing: (instance?: number) => BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: number; }>; neverDelayPublishing: () => BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: 0; }>; }
|
||||
>"maxMsToWaitBeforePublishing" in soFar : boolean
|
||||
>"maxMsToWaitBeforePublishing" : "maxMsToWaitBeforePublishing"
|
||||
>soFar : SO_FAR
|
||||
>{} : {}
|
||||
>{ maxMsToWaitBeforePublishing: (instance: number = 0) => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}>, neverDelayPublishing: () => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}>, } : { maxMsToWaitBeforePublishing: (instance?: number) => BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: number; }>; neverDelayPublishing: () => BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: 0; }>; }
|
||||
|
||||
maxMsToWaitBeforePublishing: (instance: number = 0) =>
|
||||
>maxMsToWaitBeforePublishing : (instance?: number) => BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: number; }>
|
||||
>(instance: number = 0) => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}> : (instance?: number) => BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: number; }>
|
||||
>instance : number
|
||||
>0 : 0
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}>,
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}> : BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: number; }>
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) : BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: number; }>
|
||||
>buildPubSubRecordType : <SO_FAR>(soFar: SO_FAR) => BuildPubSubRecordType<SO_FAR>
|
||||
>Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance}) : SO_FAR & { maxMsToWaitBeforePublishing: number; }
|
||||
>Object.assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>Object : ObjectConstructor
|
||||
>assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>{} : {}
|
||||
>soFar : SO_FAR
|
||||
>{maxMsToWaitBeforePublishing: instance} : { maxMsToWaitBeforePublishing: number; }
|
||||
>maxMsToWaitBeforePublishing : number
|
||||
>instance : number
|
||||
>maxMsToWaitBeforePublishing : number
|
||||
|
||||
neverDelayPublishing: () =>
|
||||
>neverDelayPublishing : () => BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: 0; }>
|
||||
>() => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}> : () => BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: 0; }>
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}>,
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}> : BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: 0; }>
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) : BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: number; }>
|
||||
>buildPubSubRecordType : <SO_FAR>(soFar: SO_FAR) => BuildPubSubRecordType<SO_FAR>
|
||||
>Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0}) : SO_FAR & { maxMsToWaitBeforePublishing: number; }
|
||||
>Object.assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>Object : ObjectConstructor
|
||||
>assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>{} : {}
|
||||
>soFar : SO_FAR
|
||||
>{maxMsToWaitBeforePublishing: 0} : { maxMsToWaitBeforePublishing: number; }
|
||||
>maxMsToWaitBeforePublishing : number
|
||||
>0 : 0
|
||||
>maxMsToWaitBeforePublishing : 0
|
||||
}
|
||||
) as MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR>;
|
||||
|
||||
type TypeConstructor<SO_FAR> =
|
||||
>TypeConstructor : TypeConstructor<SO_FAR>
|
||||
|
||||
SO_FAR extends {identifier: any, record: any, maxMsToWaitBeforePublishing: number, storedAs: PubSubRecordIsStoredInRedisAsA} ? {
|
||||
>identifier : any
|
||||
>record : any
|
||||
>maxMsToWaitBeforePublishing : number
|
||||
>storedAs : PubSubRecordIsStoredInRedisAsA
|
||||
|
||||
type: SO_FAR,
|
||||
>type : SO_FAR
|
||||
|
||||
fields: Set<keyof SO_FAR>,
|
||||
>fields : Set<keyof SO_FAR>
|
||||
|
||||
hasField: (fieldName: string | number | symbol) => fieldName is keyof SO_FAR
|
||||
>hasField : (fieldName: string | number | symbol) => fieldName is keyof SO_FAR
|
||||
>fieldName : string | number | symbol
|
||||
|
||||
} : {}
|
||||
|
||||
const buildType = <SO_FAR>(soFar: SO_FAR) => (
|
||||
>buildType : <SO_FAR>(soFar: SO_FAR) => { type?: undefined; fields?: undefined; hasField?: undefined; } | { type: SO_FAR; fields: () => Set<keyof SO_FAR>; hasField: (fieldName: string | number | symbol) => boolean; }
|
||||
><SO_FAR>(soFar: SO_FAR) => ( "identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar && "PubSubRecordIsStoredInRedisAsA" in soFar ? {} : { type: soFar, fields: () => new Set(Object.keys(soFar) as (keyof SO_FAR)[]), hasField: (fieldName: string | number | symbol) => fieldName in soFar } ) : <SO_FAR>(soFar: SO_FAR) => { type?: undefined; fields?: undefined; hasField?: undefined; } | { type: SO_FAR; fields: () => Set<keyof SO_FAR>; hasField: (fieldName: string | number | symbol) => boolean; }
|
||||
>soFar : SO_FAR
|
||||
>( "identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar && "PubSubRecordIsStoredInRedisAsA" in soFar ? {} : { type: soFar, fields: () => new Set(Object.keys(soFar) as (keyof SO_FAR)[]), hasField: (fieldName: string | number | symbol) => fieldName in soFar } ) : {} | { type: SO_FAR; fields: () => Set<keyof SO_FAR>; hasField: (fieldName: string | number | symbol) => boolean; }
|
||||
|
||||
"identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar && "PubSubRecordIsStoredInRedisAsA" in soFar ? {} : {
|
||||
>"identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar && "PubSubRecordIsStoredInRedisAsA" in soFar ? {} : { type: soFar, fields: () => new Set(Object.keys(soFar) as (keyof SO_FAR)[]), hasField: (fieldName: string | number | symbol) => fieldName in soFar } : {} | { type: SO_FAR; fields: () => Set<keyof SO_FAR>; hasField: (fieldName: string | number | symbol) => boolean; }
|
||||
>"identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar && "PubSubRecordIsStoredInRedisAsA" in soFar : boolean
|
||||
>"identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar : boolean
|
||||
>"identifier" in soFar && "object" in soFar : boolean
|
||||
>"identifier" in soFar : boolean
|
||||
>"identifier" : "identifier"
|
||||
>soFar : SO_FAR
|
||||
>"object" in soFar : boolean
|
||||
>"object" : "object"
|
||||
>soFar : SO_FAR
|
||||
>"maxMsToWaitBeforePublishing" in soFar : boolean
|
||||
>"maxMsToWaitBeforePublishing" : "maxMsToWaitBeforePublishing"
|
||||
>soFar : SO_FAR
|
||||
>"PubSubRecordIsStoredInRedisAsA" in soFar : boolean
|
||||
>"PubSubRecordIsStoredInRedisAsA" : "PubSubRecordIsStoredInRedisAsA"
|
||||
>soFar : SO_FAR
|
||||
>{} : {}
|
||||
>{ type: soFar, fields: () => new Set(Object.keys(soFar) as (keyof SO_FAR)[]), hasField: (fieldName: string | number | symbol) => fieldName in soFar } : { type: SO_FAR; fields: () => Set<keyof SO_FAR>; hasField: (fieldName: string | number | symbol) => boolean; }
|
||||
|
||||
type: soFar,
|
||||
>type : SO_FAR
|
||||
>soFar : SO_FAR
|
||||
|
||||
fields: () => new Set(Object.keys(soFar) as (keyof SO_FAR)[]),
|
||||
>fields : () => Set<keyof SO_FAR>
|
||||
>() => new Set(Object.keys(soFar) as (keyof SO_FAR)[]) : () => Set<keyof SO_FAR>
|
||||
>new Set(Object.keys(soFar) as (keyof SO_FAR)[]) : Set<keyof SO_FAR>
|
||||
>Set : SetConstructor
|
||||
>Object.keys(soFar) as (keyof SO_FAR)[] : (keyof SO_FAR)[]
|
||||
>Object.keys(soFar) : string[]
|
||||
>Object.keys : (o: {}) => string[]
|
||||
>Object : ObjectConstructor
|
||||
>keys : (o: {}) => string[]
|
||||
>soFar : SO_FAR
|
||||
|
||||
hasField: (fieldName: string | number | symbol) => fieldName in soFar
|
||||
>hasField : (fieldName: string | number | symbol) => boolean
|
||||
>(fieldName: string | number | symbol) => fieldName in soFar : (fieldName: string | number | symbol) => boolean
|
||||
>fieldName : string | number | symbol
|
||||
>fieldName in soFar : boolean
|
||||
>fieldName : string | number | symbol
|
||||
>soFar : SO_FAR
|
||||
}
|
||||
);
|
||||
|
||||
type BuildPubSubRecordType<SO_FAR> =
|
||||
>BuildPubSubRecordType : BuildPubSubRecordType<SO_FAR>
|
||||
|
||||
NameFieldConstructor<SO_FAR> &
|
||||
IdentifierFieldConstructor<SO_FAR> &
|
||||
RecordFieldConstructor<SO_FAR> &
|
||||
StoredAsConstructor<SO_FAR> & // infinite loop goes away when you comment out this line
|
||||
MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> &
|
||||
TypeConstructor<SO_FAR>
|
||||
|
||||
const buildPubSubRecordType = <SO_FAR>(soFar: SO_FAR) => Object.assign(
|
||||
>buildPubSubRecordType : <SO_FAR>(soFar: SO_FAR) => BuildPubSubRecordType<SO_FAR>
|
||||
><SO_FAR>(soFar: SO_FAR) => Object.assign( {}, buildNameFieldConstructor(soFar), buildIdentifierFieldConstructor(soFar), buildRecordFieldConstructor(soFar), buildStoredAsConstructor(soFar), buildMaxMsToWaitBeforePublishingFieldConstructor(soFar), buildType(soFar) ) as BuildPubSubRecordType<SO_FAR> : <SO_FAR>(soFar: SO_FAR) => BuildPubSubRecordType<SO_FAR>
|
||||
>soFar : SO_FAR
|
||||
>Object.assign( {}, buildNameFieldConstructor(soFar), buildIdentifierFieldConstructor(soFar), buildRecordFieldConstructor(soFar), buildStoredAsConstructor(soFar), buildMaxMsToWaitBeforePublishingFieldConstructor(soFar), buildType(soFar) ) as BuildPubSubRecordType<SO_FAR> : BuildPubSubRecordType<SO_FAR>
|
||||
>Object.assign( {}, buildNameFieldConstructor(soFar), buildIdentifierFieldConstructor(soFar), buildRecordFieldConstructor(soFar), buildStoredAsConstructor(soFar), buildMaxMsToWaitBeforePublishingFieldConstructor(soFar), buildType(soFar) ) : any
|
||||
>Object.assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>Object : ObjectConstructor
|
||||
>assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
|
||||
{},
|
||||
>{} : {}
|
||||
|
||||
buildNameFieldConstructor(soFar),
|
||||
>buildNameFieldConstructor(soFar) : { name?: undefined; } | { name: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { name: TYPE; }>; }
|
||||
>buildNameFieldConstructor : <SO_FAR>(soFar: SO_FAR) => { name?: undefined; } | { name: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { name: TYPE; }>; }
|
||||
>soFar : SO_FAR
|
||||
|
||||
buildIdentifierFieldConstructor(soFar),
|
||||
>buildIdentifierFieldConstructor(soFar) : { identifier?: undefined; } | { identifier: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { identifier: TYPE; }>; }
|
||||
>buildIdentifierFieldConstructor : <SO_FAR>(soFar: SO_FAR) => { identifier?: undefined; } | { identifier: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { identifier: TYPE; }>; }
|
||||
>soFar : SO_FAR
|
||||
|
||||
buildRecordFieldConstructor(soFar),
|
||||
>buildRecordFieldConstructor(soFar) : { record?: undefined; } | { record: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { record: TYPE; }>; }
|
||||
>buildRecordFieldConstructor : <SO_FAR>(soFar: SO_FAR) => { record?: undefined; } | { record: <TYPE>(instance?: TYPE) => BuildPubSubRecordType<SO_FAR & { record: TYPE; }>; }
|
||||
>soFar : SO_FAR
|
||||
|
||||
buildStoredAsConstructor(soFar),
|
||||
>buildStoredAsConstructor(soFar) : { storedAsJsonEncodedRedisString?: undefined; storedAsRedisHash?: undefined; } | { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString; }>; storedAsRedisHash: () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.redisHash; }>; }
|
||||
>buildStoredAsConstructor : <SO_FAR>(soFar: SO_FAR) => { storedAsJsonEncodedRedisString?: undefined; storedAsRedisHash?: undefined; } | { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString; }>; storedAsRedisHash: () => BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.redisHash; }>; }
|
||||
>soFar : SO_FAR
|
||||
|
||||
buildMaxMsToWaitBeforePublishingFieldConstructor(soFar),
|
||||
>buildMaxMsToWaitBeforePublishingFieldConstructor(soFar) : MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR>
|
||||
>buildMaxMsToWaitBeforePublishingFieldConstructor : <SO_FAR>(soFar: SO_FAR) => MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR>
|
||||
>soFar : SO_FAR
|
||||
|
||||
buildType(soFar)
|
||||
>buildType(soFar) : { type?: undefined; fields?: undefined; hasField?: undefined; } | { type: SO_FAR; fields: () => Set<keyof SO_FAR>; hasField: (fieldName: string | number | symbol) => boolean; }
|
||||
>buildType : <SO_FAR>(soFar: SO_FAR) => { type?: undefined; fields?: undefined; hasField?: undefined; } | { type: SO_FAR; fields: () => Set<keyof SO_FAR>; hasField: (fieldName: string | number | symbol) => boolean; }
|
||||
>soFar : SO_FAR
|
||||
|
||||
) as BuildPubSubRecordType<SO_FAR>;
|
||||
const PubSubRecordType = buildPubSubRecordType({});
|
||||
>PubSubRecordType : BuildPubSubRecordType<{}>
|
||||
>buildPubSubRecordType({}) : BuildPubSubRecordType<{}>
|
||||
>buildPubSubRecordType : <SO_FAR>(soFar: SO_FAR) => BuildPubSubRecordType<SO_FAR>
|
||||
>{} : {}
|
||||
|
||||
@ -17,12 +17,8 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(103,5): error TS2
|
||||
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 '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 'never'.
|
||||
Type 'string | number | symbol' is not assignable to type 'never'.
|
||||
Type 'string' 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 '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 'never'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes1.ts(114,5): error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
|
||||
Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
|
||||
Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
|
||||
@ -187,15 +183,11 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS
|
||||
~
|
||||
!!! 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]>'.
|
||||
!!! 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 'never'.
|
||||
!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'never'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'never'.
|
||||
z = x;
|
||||
z = y; // Error
|
||||
~
|
||||
!!! 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]>'.
|
||||
!!! 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 'never'.
|
||||
}
|
||||
|
||||
function f8<T>(x: keyof T, y: FunctionPropertyNames<T>, z: NonFunctionPropertyNames<T>) {
|
||||
|
||||
@ -58,8 +58,6 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(67,1): error TS2322: Type 'Fun
|
||||
Type 'Object' is not assignable to type 'string'.
|
||||
tests/cases/compiler/strictFunctionTypesErrors.ts(74,1): error TS2322: Type 'Func<Object, Func<string, void>>' is not assignable to type 'Func<Object, Func<Object, void>>'.
|
||||
Type 'Func<string, void>' is not assignable to type 'Func<Object, void>'.
|
||||
Types of parameters 'x' and 'x' are incompatible.
|
||||
Type 'Object' is not assignable to type 'string'.
|
||||
tests/cases/compiler/strictFunctionTypesErrors.ts(75,1): error TS2322: Type 'Func<string, Func<Object, void>>' is not assignable to type 'Func<Object, Func<Object, void>>'.
|
||||
Types of parameters 'x' and 'x' are incompatible.
|
||||
Type 'Object' is not assignable to type 'string'.
|
||||
@ -261,8 +259,6 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(155,5): error TS2322: Type '(c
|
||||
~~
|
||||
!!! error TS2322: Type 'Func<Object, Func<string, void>>' is not assignable to type 'Func<Object, Func<Object, void>>'.
|
||||
!!! error TS2322: Type 'Func<string, void>' is not assignable to type 'Func<Object, void>'.
|
||||
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
|
||||
!!! error TS2322: Type 'Object' is not assignable to type 'string'.
|
||||
i1 = i3; // Error
|
||||
~~
|
||||
!!! error TS2322: Type 'Func<string, Func<Object, void>>' is not assignable to type 'Func<Object, Func<Object, void>>'.
|
||||
|
||||
119
tests/cases/compiler/conditionalTypeDoesntSpinForever.ts
Normal file
119
tests/cases/compiler/conditionalTypeDoesntSpinForever.ts
Normal file
@ -0,0 +1,119 @@
|
||||
// @target: es6
|
||||
// A *self-contained* demonstration of the problem follows...
|
||||
// Test this by running `tsc --target es6` on the command-line, rather than through another build tool such as Gulp, Webpack, etc.
|
||||
|
||||
export enum PubSubRecordIsStoredInRedisAsA {
|
||||
redisHash = "redisHash",
|
||||
jsonEncodedRedisString = "jsonEncodedRedisString"
|
||||
}
|
||||
|
||||
export interface PubSubRecord<NAME extends string, RECORD, IDENTIFIER extends Partial<RECORD>> {
|
||||
name: NAME;
|
||||
record: RECORD;
|
||||
identifier: IDENTIFIER;
|
||||
storedAs: PubSubRecordIsStoredInRedisAsA;
|
||||
maxMsToWaitBeforePublishing: number;
|
||||
}
|
||||
|
||||
type NameFieldConstructor<SO_FAR> =
|
||||
SO_FAR extends {name: any} ? {} : {
|
||||
name: <TYPE>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & {name: TYPE}>
|
||||
}
|
||||
|
||||
const buildNameFieldConstructor = <SO_FAR>(soFar: SO_FAR) => (
|
||||
"name" in soFar ? {} : {
|
||||
name: <TYPE>(instance: TYPE = undefined) =>
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType<SO_FAR & {name: TYPE}>
|
||||
}
|
||||
);
|
||||
|
||||
type StoredAsConstructor<SO_FAR> =
|
||||
SO_FAR extends {storedAs: any} ? {} : {
|
||||
storedAsJsonEncodedRedisString: () => BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}>;
|
||||
storedRedisHash: () => BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}>;
|
||||
}
|
||||
|
||||
const buildStoredAsConstructor = <SO_FAR>(soFar: SO_FAR) => (
|
||||
"storedAs" in soFar ? {} : {
|
||||
storedAsJsonEncodedRedisString: () =>
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as
|
||||
BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}>,
|
||||
storedAsRedisHash: () =>
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as
|
||||
BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}>,
|
||||
}
|
||||
);
|
||||
|
||||
type IdentifierFieldConstructor<SO_FAR> =
|
||||
SO_FAR extends {identifier: any} ? {} :
|
||||
SO_FAR extends {record: any} ? {
|
||||
identifier: <TYPE extends Partial<SO_FAR["record"]>>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & {identifier: TYPE}>
|
||||
} : {}
|
||||
|
||||
const buildIdentifierFieldConstructor = <SO_FAR>(soFar: SO_FAR) => (
|
||||
"identifier" in soFar || (!("record" in soFar)) ? {} : {
|
||||
identifier: <TYPE>(instance: TYPE = undefined) =>
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType<SO_FAR & {identifier: TYPE}>
|
||||
}
|
||||
);
|
||||
|
||||
type RecordFieldConstructor<SO_FAR> =
|
||||
SO_FAR extends {record: any} ? {} : {
|
||||
record: <TYPE>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & {record: TYPE}>
|
||||
}
|
||||
|
||||
const buildRecordFieldConstructor = <SO_FAR>(soFar: SO_FAR) => (
|
||||
"record" in soFar ? {} : {
|
||||
record: <TYPE>(instance: TYPE = undefined) =>
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType<SO_FAR & {record: TYPE}>
|
||||
}
|
||||
);
|
||||
|
||||
type MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> =
|
||||
SO_FAR extends {maxMsToWaitBeforePublishing: any} ? {} : {
|
||||
maxMsToWaitBeforePublishing: (t: number) => BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}>,
|
||||
neverDelayPublishing: () => BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}>,
|
||||
}
|
||||
|
||||
const buildMaxMsToWaitBeforePublishingFieldConstructor = <SO_FAR>(soFar: SO_FAR): MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> => (
|
||||
"maxMsToWaitBeforePublishing" in soFar ? {} : {
|
||||
maxMsToWaitBeforePublishing: (instance: number = 0) =>
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}>,
|
||||
neverDelayPublishing: () =>
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}>,
|
||||
}
|
||||
) as MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR>;
|
||||
|
||||
type TypeConstructor<SO_FAR> =
|
||||
SO_FAR extends {identifier: any, record: any, maxMsToWaitBeforePublishing: number, storedAs: PubSubRecordIsStoredInRedisAsA} ? {
|
||||
type: SO_FAR,
|
||||
fields: Set<keyof SO_FAR>,
|
||||
hasField: (fieldName: string | number | symbol) => fieldName is keyof SO_FAR
|
||||
} : {}
|
||||
|
||||
const buildType = <SO_FAR>(soFar: SO_FAR) => (
|
||||
"identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar && "PubSubRecordIsStoredInRedisAsA" in soFar ? {} : {
|
||||
type: soFar,
|
||||
fields: () => new Set(Object.keys(soFar) as (keyof SO_FAR)[]),
|
||||
hasField: (fieldName: string | number | symbol) => fieldName in soFar
|
||||
}
|
||||
);
|
||||
|
||||
type BuildPubSubRecordType<SO_FAR> =
|
||||
NameFieldConstructor<SO_FAR> &
|
||||
IdentifierFieldConstructor<SO_FAR> &
|
||||
RecordFieldConstructor<SO_FAR> &
|
||||
StoredAsConstructor<SO_FAR> & // infinite loop goes away when you comment out this line
|
||||
MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> &
|
||||
TypeConstructor<SO_FAR>
|
||||
|
||||
const buildPubSubRecordType = <SO_FAR>(soFar: SO_FAR) => Object.assign(
|
||||
{},
|
||||
buildNameFieldConstructor(soFar),
|
||||
buildIdentifierFieldConstructor(soFar),
|
||||
buildRecordFieldConstructor(soFar),
|
||||
buildStoredAsConstructor(soFar),
|
||||
buildMaxMsToWaitBeforePublishingFieldConstructor(soFar),
|
||||
buildType(soFar)
|
||||
) as BuildPubSubRecordType<SO_FAR>;
|
||||
const PubSubRecordType = buildPubSubRecordType({});
|
||||
Loading…
x
Reference in New Issue
Block a user