-
-
Notifications
You must be signed in to change notification settings - Fork 213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Covariance (?) bug: pipe checks type assignability in a wrong "direction" #979
Comments
Thank you for creating this issue. Currently, |
AFAIK Here is my case: const accountIdSchemaObj = v.object({
signatory: v.pipe(
v.string(),
v.hexadecimal(),
v.transform((hex) => PublicKey.fromMultihash(hex)),
),
domain: DomainIdSchema,
})
const AccountIdSchema = v.pipe(
v.union([
accountIdSchemaObj,
v.pipe(
v.string(),
v.rawTransform(({ dataset, addIssue, NEVER }) => {
const input = dataset.value
const parts = input.split('@')
if (parts.length !== 2) {
addIssue({ message: `AccountId should have format '⟨signatory⟩@⟨domain⟩', got: '${input}'` })
return NEVER
}
const [signatory, domain] = parts
return { signatory, domain }
}),
accountIdSchemaObj,
),
]),
v.transform((x) => new AccountId(x.signatory, x.domain)),
)
const assetDefIdSchemaObj = v.object({ name: NameSchema, domain: DomainIdSchema })
const AssetDefinitionIdSchema = v.pipe(
v.union([
v.pipe(
v.string(),
v.rawTransform(({ dataset: { value: input }, addIssue, NEVER }) => {
const parts = input.split('#')
if (parts.length !== 2) {
addIssue({ message: `AssetDefinitionId should have format '⟨name⟩@⟨domain⟩', got '${input}'` })
return NEVER
}
const [name, domain] = parts
return { name, domain }
}),
assetDefIdSchemaObj,
),
assetDefIdSchemaObj,
]),
v.transform((x) => new AssetDefinitionId(x.name, x.domain)),
)
const AssetIdSchema = v.pipe(
v.string(),
v.rawTransform(({ dataset: { value: input }, addIssue, NEVER }) => {
const match = input.match(/^(.+)#(.+)?#(.+)@(.+)$/)
if (!match) {
addIssue({
message:
`AssetId should have format '⟨name⟩#⟨asset domain⟩#⟨account signatory⟩@⟨account domain⟩' ` +
`or '⟨name⟩##⟨account signatory⟩@⟨account domain⟩' (when asset and account domains are the same), got '${input}'`,
})
return NEVER
}
const [, asset, domain1, account, domain2] = match
return {
account: { signatory: account, domain: domain2 },
definition: { name: asset, domain: domain1 ?? domain2 },
}
}),
v.object({
account: AccountIdSchema,
definition: AssetDefinitionIdSchema,
}) as v.GenericSchema<
{ account: { signatory: string; domain: string }; definition: { name: string; domain: string } },
{ account: AccountId; definition: AssetDefinitionId }
>,
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^ issue is here
v.transform((x) => new AssetId(x.account, x.definition)),
) where So, I have a "waterfall" of parsing here: Is there an idiomatic way to build such a pipeline in Valibot? |
Minimal reproduction
Expected
Should work -
SchemaA
accepts bothstring
andnumber
as input.Actual
SchemaA
isn't allowed inpipe
afterv.string()
:So, although you would expect that the input type of
SchemaA
should extend the output type ofv.string()
, it seems it works vice versa and requires the output type ofv.string()
to extend the input type ofSchemaA
.Workaround
I have to cast the schema with "wrong requirements" explicitly:
The text was updated successfully, but these errors were encountered: