Effect-TS / effect

An ecosystem of tools for building production-grade applications in TypeScript.

Home Page:https://effect.website

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Generic Schema.Struct doesn't simplify in typescript

joepjoosten opened this issue · comments

What version of Effect is running?

3.1.2, @effect/schema 0.66.15, Typescript 5.4.5

What steps can reproduce the bug?

import { Schema } from '@effect/schema';

const GenericStruct = <T extends Schema.Schema.All>(x: T) =>
  Schema.Struct({
    x: x,
  });

const obj = GenericStruct(Schema.Number);
// Schema.Struct<{
//    x: Schema.$Number;
// }>

export type GenericStruct<T extends Schema.Schema.All> = Schema.Schema.Type<ReturnType<typeof GenericStruct<T>>>;

function doesNotCompile<T extends Schema.Schema.All>(obj: GenericStruct<T>) {
  obj.x; // <-- Property 'x' does not exist on type 'Simplify<Type<{ x: T; }>>'.ts(2339)
}

What is the expected behavior?

I expect the obj.x to be available in the function, but it does not simplify in typescript.

What do you see instead?

Property 'x' does not exist on type 'Simplify<Type<{ x: T; }>>'.ts(2339)

Additional information

If tried this in the TS playground, to see if this is a typescript problem:

type Simplify<A> = {
  [K in keyof A]: A[K]
} extends infer B ? B : never

type X<S extends String> = Simplify<{ x: S }>

function b<S extends String>(a: X<S>) {
    a.x
}

https://www.typescriptlang.org/play/#code/C4TwDgpgBAyglgWzAGzgMxAHgIID4oC8UA3gFBRQDaA0lHAHZQDWEIA9mlNgLoBcXNbqQC+UCAA9gEegBMAznXpoIAJygAhKAH4NUfvQgA3VaVKhIUABqYYYydPmxgKhgHN8ReElQZMxKOL8tsK4pmgArvQAxsBwbIwARjZ2UrIKMM5uuAAUAIb81jC4AJQk5BRQuQB04iJAA

But this works, but it's not the full example because of the Schema.Schema.Type

I think it's necessary to force TypeScript to resolve the conditional type of Schema.Schema.Type:

export type Type<S> = S extends Schema.Variance<infer A, infer _I, infer _R> ? A : never

for example

type AsSchema<T extends Schema.Schema.All> = Schema.Schema<
  Schema.Schema.Type<T>,
  Schema.Schema.Encoded<T>,
  Schema.Schema.Context<T>
>

function doesNotCompile<T extends Schema.Schema.All>(obj: GenericStruct<AsSchema<T>>) {
  obj.x // Schema.Schema.Type<T>
}

Is the AsSchema function somewhere in the Schema package? if not, should it be a nice helper function, and explain it in the docs when using generics?

I see there is a asSchema value, but no type definition