Skip to content

Commit

Permalink
Merge pull request #67 from saiichihashimoto/infer-named-types
Browse files Browse the repository at this point in the history
feat(types): infer types from sanity configs
  • Loading branch information
kodiakhq[bot] authored Jun 15, 2023
2 parents 6ef12ea + d9fc92a commit 6e979a3
Show file tree
Hide file tree
Showing 5 changed files with 411 additions and 120 deletions.
6 changes: 4 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 14 additions & 7 deletions packages/types/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ npm install @sanity-typed/types sanity

## Usage

Use `defineConfig`, `defineType`, `defineField`, and `defineArrayMember` from this library exactly as you would from [sanity's own exports](https://www.sanity.io/docs/schema-field-types#e5642a3e8506). Then, you can `InferValue` to have the typescript type!
Use `defineConfig`, `defineType`, `defineField`, and `defineArrayMember` from this library exactly as you would from [sanity's own exports](https://www.sanity.io/docs/schema-field-types#e5642a3e8506). Then, you can `InferSchemaValues` to have the typescript types!

```typescript
// import { defineArrayMember, defineConfig, defineField, defineType } from "sanity";
Expand All @@ -27,8 +27,7 @@ import {
defineField,
defineType,
} from "@sanity-typed/types";
// This is where the magic happens!
import type { InferValue } from "@sanity-typed/types";
import type { InferSchemaValues } from "@sanity-typed/types";

// Corresponding example: https://www.sanity.io/docs/schema-field-types#e5642a3e8506
// No changes using defineArrayMember, defineField, and defineArrayMember https://www.sanity.io/docs/schema-field-types
Expand Down Expand Up @@ -61,15 +60,23 @@ const product = defineType({
});

// No changes using defineConfig https://www.sanity.io/docs/config-api-reference
export default defineConfig({
const config = defineConfig({
// ...
schema: {
types: [product],
types: [
product,
// ...
],
},
});

export default config;

// This is where the magic happens!
type Values = InferSchemaValues<typeof config>;

// Import Product type into your application!
export type Product = InferValue<typeof product>;
export type Product = Extract<Values, { _type: "product" }>;
/**
* Product === {
* _createdAt: string;
Expand All @@ -90,6 +97,6 @@ export type Product = InferValue<typeof product>;

Typescript was an after-the-fact concern with sanity, since the rise of typescript happened after sanity took off. The `define*` methods are a good start, but they only help restrict the schema, not type the document types. There's been attempts, namely [`sanity-codegen`](https://github.com/ricokahler/sanity-codegen) and [`@sanity-typed/schema-builder`](https://github.com/saiichihashimoto/sanity-typed/tree/main/packages/schema-builder), but they take the approach of creating a new way of building schemas. The drop-in replacement approach allows for zero migration cost.

The long term goal is to deprecate `@sanity-typed/types` altogether. Building this seperately was in service of moving quickly and these should be in sanity directly (and is likely one of their internal goals). The idea is to introduce these changes iteratively into sanity itself while removing them from this library, until it's reduced to simply passing through the `define*` methods directly, and will then be deprecated.
The long term goal is to deprecate the monorepo altogether. Building this seperately was to move quickly and these features should be in sanity directly (and is likely one of their internal goals). The idea is to introduce these changes iteratively into sanity itself while removing them from this library, until it's reduced to simply passing through the `define*` methods directly, and will then be deprecated.

This shouldn't deter you from using it! Under the hood, it's passing all the inputs to sanity's native `define*` methods, so you shouldn't have any runtime differences. With all the typings being attempting to make their way into sanity, you should keep all the benefits of just importing the `define*` methods and noticing no differences.
6 changes: 4 additions & 2 deletions packages/types/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
"@portabletext/types": "2.0.2",
"@sanity-typed/test-utils": "0.0.0-development",
"@sanity-typed/tsconfig": "0.0.0-development",
"sanity": "3.12.0"
"sanity": "3.12.0",
"typescript": "5.0.4"
},
"peerDependencies": {
"@portabletext/types": "^2.0.2",
"sanity": "^3.12.0"
"sanity": "^3.12.0",
"typescript": "^5.0.4"
}
}
Loading

0 comments on commit 6e979a3

Please sign in to comment.