gray-matter icon indicating copy to clipboard operation
gray-matter copied to clipboard

Allow type of "data" property to be set using generic type

Open FunctionDJ opened this issue 2 years ago • 3 comments

Right now there is no way to set the type of file.data except with as. In general, as in TypeScript conveys incomplete typings for external libraries or insufficient time to fix an issue with types. You want to reduce as in a code base as much as possible in order for it to be a red flag when it comes up. However, with I/O we tap outside of types and telling our code which shape a resulting object will have is necessary. Other libraries achieve this by simply exposing a generic type param on classes or methods like this:

interface MyFrontMatter {
  title: string
  date: string
}

const { data } = matter<string, {}, MyFrontMatter>(fileContents);
const { title, date } = data; // statically typed, TS knows that title is a string, not 'any'

The advantage is that this conveys intent, that the typings are as clean as they can be. It would be great if you could add this as a third param to the types!

declare function matter<
  I extends matter.Input,
  O extends matter.GrayMatterOption<I, O>,
  MatterShape extends Record<string, unknown> // not sure about this
>(input: I | { content: I }, options?: O): matter.GrayMatterFile<I, MatterShape>

// ...

  interface GrayMatterFile<I extends Input, MatterShape extends Record<string, unknown>> {
    data: MatterShape
    content: string
    excerpt?: string
    orig: Buffer | I
    language: string
    matter: string
    stringify(lang: string): string
  }```

FunctionDJ avatar Jan 22 '22 23:01 FunctionDJ

++ Yes. This would be quite helpful.

rocktimsaikia avatar Mar 04 '22 15:03 rocktimsaikia

yse, I have this, It kind of bothers me

gd-cho avatar Apr 05 '22 16:04 gd-cho

As I've encountered this limitation multiple times, I created a small wrapper for gray-matter using zod to actually validate front matter and get proper type inference, e.g.:

import { parse } from 'zod-matter'
import { z } from 'zod'

const { data } = parse('---\nauthor: HiDeoo\n---\n# Hello world!', z.object({ author: z.string() }))
//       ^? { author: string }

HiDeoo avatar Jan 05 '23 18:01 HiDeoo