feat (client): extensible value type for use with custom parsers
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)
},
},
})
Thanks @kevin-dp, that will solve my problem.
@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 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!