import {expectAssignable, expectNotAssignable, expectType} from 'tsd'; import type {InvariantOf, InvariantOfDeep} from '.'; declare const invariantString: InvariantOf; declare const invariantStringOrNumber: InvariantOf; declare const invariantSomeString: InvariantOf<'someString'>; expectNotAssignable>(invariantSomeString); expectNotAssignable>(invariantSomeString); expectNotAssignable>(invariantString); expectNotAssignable>(invariantStringOrNumber); type BaseType = { foo: number; bar?: string; }; type SubType = BaseType & { baz: number | undefined; }; type SameType = { foo: number; bar?: string; }; interface BaseInterface { foo: number; bar?: string; } interface SubInterface extends BaseInterface { baz: number | undefined; } interface SameInterface { foo: number; bar?: string; } class BaseClass { declare foo: number; declare bar?: string; } class SubClass extends BaseClass { declare baz: number | undefined; } class SameClass { declare foo: number; declare bar?: string; } declare const baseTypeValue: BaseType; declare const invariantBaseTypeValue: InvariantOf; declare const invariantBaseInterfaceValue: InvariantOf; declare const invariantBaseClassInstanceValue: InvariantOf; declare const sameTypeValue: SameType; declare const invariantSameTypeValue: InvariantOf; declare const invariantSameInterfaceValue: InvariantOf; declare const invariantSameClassInstanceValue: InvariantOf; declare const subTypeValue: SubType; declare const invariantSubTypeValue: InvariantOf; declare const invariantSubInterfaceValue: InvariantOf; declare const invariantSubClassInstanceValue: InvariantOf; /** Invariance does accept same type */ expectType(baseTypeValue); expectType>(invariantBaseTypeValue); expectType>(invariantBaseInterfaceValue); expectType>(invariantBaseClassInstanceValue); /** Invariance does accept equal structure type */ expectType(sameTypeValue); expectType>(invariantSameTypeValue); expectType>(invariantSameInterfaceValue); expectType>(invariantSameClassInstanceValue); /** Invariance does not accept sub type */ expectAssignable(subTypeValue); expectNotAssignable>(invariantSubTypeValue); expectNotAssignable>(invariantSubInterfaceValue); expectNotAssignable>(invariantSubClassInstanceValue); /** Invariance does not accept super type */ expectNotAssignable(baseTypeValue); expectNotAssignable>(invariantBaseTypeValue); expectNotAssignable>(invariantBaseInterfaceValue); expectNotAssignable>(invariantBaseClassInstanceValue); /** Invariant type is subtype of default type */ expectAssignable(invariantBaseTypeValue); expectAssignable(invariantBaseInterfaceValue); expectAssignable(invariantBaseClassInstanceValue); type DeepBaseType = { foo: number; bar?: BaseType; }; declare const invariantOfDeepBaseType: InvariantOfDeep; expectType< InvariantOf<{ foo: InvariantOf; bar?: InvariantOf<{ foo: InvariantOf; bar?: InvariantOf; }>; }> >(invariantOfDeepBaseType); expectType>(invariantOfDeepBaseType.foo); expectType | undefined>(invariantOfDeepBaseType.bar); expectType | undefined>(invariantOfDeepBaseType.bar?.bar); expectType | undefined>(invariantOfDeepBaseType.bar?.foo);