Kind<F, In, Out2, Out1, Target>Applies type parameters to a TypeLambda to get the concrete type.
When to use
Use to apply a TypeLambda to type parameters and obtain its concrete type.
Details
This type-level function takes a TypeLambda and four type parameters, then
"applies" them to get the actual type. It handles variance correctly, ensuring
contravariant parameters are used as inputs and covariant parameters as
outputs. This is the core mechanism that allows HKT to transform abstract type
constructors into concrete types by applying arguments.
Example (Applying type lambdas)
import type { Effect, HKT, Option } from "effect"
// Define TypeLambdas
interface OptionTypeLambda extends HKT.TypeLambda {
readonly type: Option.Option<this["Target"]>
}
interface EffectTypeLambda extends HKT.TypeLambda {
readonly type: Effect.Effect<this["Target"], this["Out2"], this["Out1"]>
}
// Apply type parameters to get concrete types
type OptionString = HKT.Kind<OptionTypeLambda, never, never, never, string>
// Result: Option.Option<string>
type EffectStringNumberBoolean = HKT.Kind<
EffectTypeLambda,
never,
number,
boolean,
string
>
// Result: Effect.Effect<string, number, boolean>
// TypeLambdas enable generic programming over type constructors
type StringType<F extends HKT.TypeLambda> = HKT.Kind<
F,
never,
never,
never,
string
>export type type Kind<
F extends TypeLambda,
In,
Out2,
Out1,
Target
> = F extends {
readonly type: unknown
}
? (F & {
readonly In: In
readonly Out2: Out2
readonly Out1: Out1
readonly Target: Target
})["type"]
: {
readonly F: F
readonly In: Types.Contravariant<In>
readonly Out2: Types.Covariant<Out2>
readonly Out1: Types.Covariant<Out1>
readonly Target: Types.Invariant<Target>
}
Applies type parameters to a TypeLambda to get the concrete type.
When to use
Use to apply a TypeLambda to type parameters and obtain its concrete type.
Details
This type-level function takes a TypeLambda and four type parameters, then
"applies" them to get the actual type. It handles variance correctly, ensuring
contravariant parameters are used as inputs and covariant parameters as
outputs. This is the core mechanism that allows HKT to transform abstract type
constructors into concrete types by applying arguments.
Example (Applying type lambdas)
import type { Effect, HKT, Option } from "effect"
// Define TypeLambdas
interface OptionTypeLambda extends HKT.TypeLambda {
readonly type: Option.Option<this["Target"]>
}
interface EffectTypeLambda extends HKT.TypeLambda {
readonly type: Effect.Effect<this["Target"], this["Out2"], this["Out1"]>
}
// Apply type parameters to get concrete types
type OptionString = HKT.Kind<OptionTypeLambda, never, never, never, string>
// Result: Option.Option<string>
type EffectStringNumberBoolean = HKT.Kind<
EffectTypeLambda,
never,
number,
boolean,
string
>
// Result: Effect.Effect<string, number, boolean>
// TypeLambdas enable generic programming over type constructors
type StringType<F extends HKT.TypeLambda> = HKT.Kind<
F,
never,
never,
never,
string
>
Kind<function (type parameter) F in type Kind<F extends TypeLambda, In, Out2, Out1, Target>F extends TypeLambda, function (type parameter) In in type Kind<F extends TypeLambda, In, Out2, Out1, Target>In, function (type parameter) Out2 in type Kind<F extends TypeLambda, In, Out2, Out1, Target>Out2, function (type parameter) Out1 in type Kind<F extends TypeLambda, In, Out2, Out1, Target>Out1, function (type parameter) Target in type Kind<F extends TypeLambda, In, Out2, Out1, Target>Target> = function (type parameter) F in type Kind<F extends TypeLambda, In, Out2, Out1, Target>F extends {
readonly type: unknowntype: unknown
} ? (function (type parameter) F in type Kind<F extends TypeLambda, In, Out2, Out1, Target>F & {
readonly type In: InIn: function (type parameter) In in type Kind<F extends TypeLambda, In, Out2, Out1, Target>In
readonly type Out2: Out2Out2: function (type parameter) Out2 in type Kind<F extends TypeLambda, In, Out2, Out1, Target>Out2
readonly type Out1: Out1Out1: function (type parameter) Out1 in type Kind<F extends TypeLambda, In, Out2, Out1, Target>Out1
readonly type Target: TargetTarget: function (type parameter) Target in type Kind<F extends TypeLambda, In, Out2, Out1, Target>Target
})["type"]
: {
readonly type F: F extends TypeLambdaF: function (type parameter) F in type Kind<F extends TypeLambda, In, Out2, Out1, Target>F
readonly type In: Types.Contravariant<In>In: import TypesTypes.type Contravariant<A> = (_: A) => voidFunction-type alias encoding contravariant variance for a phantom type
parameter.
When to use
Use as a phantom field type to make a type parameter contravariant in input
position.
Details
Contravariant<A> is assignable to Contravariant<B> when B extends A,
following the supertype direction.
Example (Defining a contravariant phantom type)
import type { Types } from "effect"
interface Consumer<T> {
readonly _phantom: Types.Contravariant<T>
readonly accept: (value: T) => void
}
Namespace for
Contravariant
-related utilities.
When to use
Use when referring to type-level helpers nested under Contravariant.
Contravariant<function (type parameter) In in type Kind<F extends TypeLambda, In, Out2, Out1, Target>In>
readonly type Out2: Types.Covariant<Out2>Out2: import TypesTypes.type Covariant<A> = (_: never) => AFunction-type alias encoding covariant variance for a phantom type
parameter.
When to use
Use as a phantom field type to make a type parameter covariant in output
position.
Details
Covariant<A> is assignable to Covariant<B> when A extends B, following
the subtype direction.
Example (Defining a covariant phantom type)
import type { Types } from "effect"
interface Producer<T> {
readonly _phantom: Types.Covariant<T>
readonly get: () => T
}
Namespace for
Covariant
-related utilities.
When to use
Use when referring to type-level helpers nested under Covariant.
Covariant<function (type parameter) Out2 in type Kind<F extends TypeLambda, In, Out2, Out1, Target>Out2>
readonly type Out1: Types.Covariant<Out1>Out1: import TypesTypes.type Covariant<A> = (_: never) => AFunction-type alias encoding covariant variance for a phantom type
parameter.
When to use
Use as a phantom field type to make a type parameter covariant in output
position.
Details
Covariant<A> is assignable to Covariant<B> when A extends B, following
the subtype direction.
Example (Defining a covariant phantom type)
import type { Types } from "effect"
interface Producer<T> {
readonly _phantom: Types.Covariant<T>
readonly get: () => T
}
Namespace for
Covariant
-related utilities.
When to use
Use when referring to type-level helpers nested under Covariant.
Covariant<function (type parameter) Out1 in type Kind<F extends TypeLambda, In, Out2, Out1, Target>Out1>
readonly type Target: Types.Invariant<Target>Target: import TypesTypes.type Invariant<A> = (_: A) => AFunction-type alias encoding invariant variance for a phantom type
parameter.
When to use
Use as a phantom field type to make a type parameter invariant, neither
covariant nor contravariant.
Details
A value of type Invariant<A> cannot be assigned to Invariant<B> unless
A and B are the same type.
Example (Defining an invariant phantom type)
import type { Types } from "effect"
interface Container<T> {
readonly _phantom: Types.Invariant<T>
readonly value: T
}
Namespace for
Invariant
-related utilities.
When to use
Use when referring to type-level helpers nested under Invariant.
Invariant<function (type parameter) Target in type Kind<F extends TypeLambda, In, Out2, Out1, Target>Target>
}