Thinkmill / Thinkmill/keystatic
`collection().columns` should allow `array` fields (runtime works, types reject them)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 2.4k
- Forks
- 159
- Avg merge
- 21h 41m
- Merged PRs (30d)
- 2
Description
Problem
We want to show an array field in a collection list view via the columns option. For example, a list of external project slugs so editors can see at a glance which entries are linked to another system:
steckbriefe: collection({
label: 'Steckbriefe',
slugField: 'slug',
path: 'src/data/steckbriefe/*/',
format: { data: 'yaml' },
columns: ['title', 'state', 'trassenscoutProjectSlugs', 'lastCheckedDate'],
schema: {
title: fields.text({ label: 'Titel', validation: { isRequired: true } }),
trassenscoutProjectSlugs: fields.array(fields.text({ label: 'Trassenscout slug' }), {
label: 'Trassenscout',
itemLabel: (props) => props.value || 'Slug',
}),
// ...
},
}),
Runtime: This works. The Admin UI renders array column values by stringifying them (val + ''), so ['rs8', 'rs8-north'] shows as rs8,rs8-north and [] shows as empty.
Types: TypeScript rejects trassenscoutProjectSlugs in columns because collection() only allows keys whose schema field is a scalar FormField or SlugFormField:
// dist/declarations/src/config.d.ts (current)
columns?: {
[K in keyof Schema]: Schema[K] extends
| FormField<any, any, string | number | boolean | Date | null | undefined>
| SlugFormField<any, any, any, string>
? K & string
: never;
}[keyof Schema][];
ArrayField (kind: 'array') is excluded even though the list view handles it fine.
Expected behavior
Array fields should be valid in columns, since the collection table already displays them.
Actual behavior
- Admin UI: works
- TypeScript: error —
Type '"trassenscoutProjectSlugs"' is not assignable to type ...
Suggested fix
Extend the columns mapped type to also allow ArrayField keys:
columns?: {
[K in keyof Schema]: Schema[K] extends
| FormField<any, any, string | number | boolean | Date | null | undefined>
| SlugFormField<any, any, any, string>
? K & string
: Schema[K] extends { kind: 'array' }
? K & string
: never;
}[keyof Schema][];
Environment
@keystatic/core: 0.5.50@keystatic/astro: 5.1.0- TypeScript: 6.x
- Package manager: Bun 1.3
Workarounds (until upstream fix)
Option A: @ts-expect-error (minimal)
steckbriefe: collection({
// Keystatic renders array columns as comma-separated values; types only allow scalars.
// @ts-expect-error array field used as list column
columns: ['title', 'state', 'trassenscoutProjectSlugs', 'lastCheckedDate'],
schema: {
trassenscoutProjectSlugs: fields.array(fields.text({ label: 'Trassenscout slug' }), {
label: 'Trassenscout',
}),
// ...
},
}),
Option B: Patch @keystatic/core (what we use)
We patch the published type definition so columns accepts array fields without suppressions.
1. Start a patch (Bun):
bun patch @keystatic/core
2. Edit node_modules/@keystatic/core/dist/declarations/src/config.d.ts:
columns?: {
- [K in keyof Schema]: Schema[K] extends FormField<any, any, string | number | boolean | Date | null | undefined> | SlugFormField<any, any, any, string> ? K & string : never;
+ [K in keyof Schema]: Schema[K] extends FormField<any, any, string | number | boolean | Date | null | undefined> | SlugFormField<any, any, any, string> ? K & string : Schema[K] extends {
+ kind: 'array';
+ } ? K & string : never;
}[keyof Schema][];
3. Commit the patch:
bun patch --commit 'node_modules/@keystatic/core'
This creates patches/@keystatic%2Fcore@0.5.50.patch and adds to package.json:
"patchedDependencies": {
"@keystatic/core@0.5.50": "patches/@keystatic%2Fcore@0.5.50.patch"
}
Bun reapplies the patch on every bun install. After upgrading @keystatic/core, regenerate the patch for the new version.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the generated declaration in dist/declarations/src/config.d.ts and locate the source declaration for collection()'s columns option. Check the existing scalar and slug field type constraints, then verify that array fields are accepted while unsupported fields remain rejected. Confirm completion with the project's TypeScript checks or type-test suite, if available.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- developer-experience
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100