electric icon indicating copy to clipboard operation
electric copied to clipboard

feat (client): extensible value type for use with custom parsers

Open kevin-dp opened this issue 1 year ago • 1 comments

This PR modifies the types of our client to enable users to extend the Value type. This is needed when using custom parsers.

For example, the parser below used to throw a type error because Date is not a Value (where Value is the type of base SQL values):

const parser: Parser = {
  timestampz: (date: string) => {
    return new Date(date)
  },
}

With this PR, we can now write this parser as:

const parser: Parser<Date> = {
  timestampz: (date: string) => {
    return new Date(date)
  },
}

And an example usage of this parser with the ShapeStream:

type CustomRow = {
  foo: number
  bar: boolean
  baz: string
  ts: Date
}

const shapeStream = new ShapeStream<CustomRow>({
  url: `...`,
  parser: {
    timestampz: (date: string) => {
      return new Date(date)
    },
  },
})

Note that this would throw an error as Date is not a type that occurs in the row:

type CustomRow = {
  foo: number
  bar: boolean
  baz: string
}

const shapeStream = new ShapeStream<CustomRow>({
  url: `...`,
  parser: {
    // type error here
    timestampz: (date: string) => {
      return new Date(date)
    },
  },
})

kevin-dp avatar Oct 03 '24 13:10 kevin-dp

Thanks @kevin-dp, that will solve my problem.

balegas avatar Oct 03 '24 14:10 balegas

@msfstef never acts as the neutral element on union types, unknown acts as the absorbing element on union types:

type Value = string | boolean | unknown
const a: Value = null // is accepted because`Test` is basically `unknown`

type Value2 = string | boolean | never
const b: Value2 = null // type error because `Test = string | boolean`

So we want never as the default because that means that if the user does not provide anything then it is correctly typed as just the base SQL types. If we would use unknown then the entire Value type would be reduced to unknown which we don't want.

kevin-dp avatar Oct 07 '24 07:10 kevin-dp

@kevin-dp ah now I see, and the default is still Row<never> for all APIs so the behaviour is still the same - thanks for the clarification, good to merge!

msfstef avatar Oct 07 '24 08:10 msfstef