Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues building dynamic fields; SchemaTypeDefinition equivalent? #703

Open
coreyward opened this issue Mar 26, 2024 · 3 comments
Open

Issues building dynamic fields; SchemaTypeDefinition equivalent? #703

coreyward opened this issue Mar 26, 2024 · 3 comments

Comments

@coreyward
Copy link

I'm exploring using sanity-typed, but with a relatively simple studio I'm running into some issues. One I am not sure how to proceed on is figuring out how to handle dynamically defined schemas. For example, I have a list of object types that are used like content modules (called "blocks" in this case). The definitions for each are exported in an array from a "blocks/index.ts" file. With the vanilla TS studio, I can do the following to define a contentBlocks type that I can use as a field elsewhere:

import { SchemaTypeDefinition, defineField } from "sanity"
import blockDefs from "../blocks"

const extractNameFromBlockDef = (
  blockDef: SchemaTypeDefinition | SchemaTypeDefinition[],
) => {
  const block = Array.isArray(blockDef)
    ? blockDef.find((def) => def.name.endsWith("Block"))
    : blockDef

  if (!block) {
    throw new Error("No block found")
  }
  return block.name
}

export default defineField({
  title: "Content Blocks",
  name: "contentBlocks",
  type: "array",
  of: blockDefs.map((block) => ({
    type: extractNameFromBlockDef(block),
  })),
})

If I convert this over to @sanity-typed/types, I wind up with a slew of TS errors, most obviously from SchemaTypeDefinition not matching what @sanity-typed/types is doing. I tried looking for an equivalent, but it seems like all of the utility types require a long list of generics to be passed in. I saw elsewhere that using as const on array members inside of might be necessary, but that doesn't really work in a scenario where the value is not actually constant like this.

Any direction or guidance on how to approach this?

@coreyward
Copy link
Author

It's seeming like @sanity-typed really doesn't work in situations where types cannot be inferred:

defineField({
  name: "example",
  type: "array",
  of: [{ type: "string" }].map((f) => defineArrayMember(f)),
})

This yields errors on of:

Type 'ArrayMemberDefinition<string, string, IntrinsicTypeName, StrictDefinition, number, string, string, false, BlockStyleDefault, BlockListItemDefault, BlockMarkDecoratorDefault, never, false, never, never, false>[]' is not assignable to type '[ArrayMemberDefinition<string, string, IntrinsicTypeName, StrictDefinition, number, string, string, false, BlockStyleDefault, BlockListItemDefault, BlockMarkDecoratorDefault, never, false, never, never, false>, ...ArrayMemberDefinition<...>[]]'.ts(2322)
internal.d.ts(126, 5): The expected type comes from property 'of' which is declared here on type 'FieldDefinition<"array", "example", IntrinsicTypeName, StrictDefinition, number, string, string, false, BlockStyleDefault, BlockListItemDefault, BlockMarkDecoratorDefault, never, false, never, ArrayMemberDefinition<string, ... 14 more ..., false>,

Normally I'd explicitly type the array to resolve this, but without the means to do so it seems like my hands are tied.

@saiichihashimoto
Copy link
Owner

SO. I'm going to remove this restriction in the next version. I think that use cases like this are unavoidable and having sanity-typed be this strict on the of field seems like more of an obstacle than a benefit. This DOES mean that you'll often get the string type where you assumed you'd get a string literal because, somewhere, you didn't do as const.

@saiichihashimoto
Copy link
Owner

When #801 gets deployed, that may help with your issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants