feathersjs / feathers

The API and real-time application framework
https://feathersjs.com
MIT License
14.97k stars 742 forks source link

Schema resolving to unknown or any with queryProperty #3413

Closed desudo closed 4 months ago

desudo commented 5 months ago

The schema is resolving into type unknown or any when using queryProperty from @feathers/schema. mytest would resolve in the structure I intend to have, Schema does not.

import { FromSchema, queryProperty } from '@feathersjs/schema';

const detailsQueryProperty = {
  // eslint-disable-next-line no-useless-escape
  '^(details.[1-9][0-9]{0,2})$': {
    ...queryProperty({ type: 'string' }),
  },
} as const;

const schema = {
  type: 'object',
  patternProperties: {
    ...detailsQueryProperty,
  },
} as const;

const myschema = {
  type: 'object',
  patternProperties: {
    '^(details.[1-9][0-9]{0,2})$': {
      anyOf: [
        { type: 'string' },
        {
          type: 'object',
          additionalProperties: false,
          properties: {
            $gt: { type: 'string' },
            $gte: { type: 'string' },
            $lt: { type: 'string' },
            $lte: { type: 'string' },
            $ne: { type: 'string' },
            $in: { type: 'array', items: { type: 'string' } },
            $nin: { type: 'array', items: { type: 'string' } },
          },
        },
      ],
    },
  },
} as const;

type mytest = FromSchema<typeof myschema>;

type Schema = FromSchema<typeof schema>;

I also have a working example, on Stackblitz: Example

Additional Information:

NodeJs: v16.20.2 npm: v8.19.4 TypeScript: v5.3.3 @feathers/schema: 5.0.14

Thanks for any help!

daffl commented 5 months ago

Pattern matching for keys like the above is not possible in TypeScript which is why it can't resolve to a known type.

desudo commented 5 months ago

Yes, that is correct. Even if I use a genuine property, queryProperty still does not resolve as you can see in the screenshot.

Screenshot 2024-01-30 at 09 47 05

When using queryProperty by itself, it does work out just fine:

Screenshot 2024-01-30 at 09 45 48

I'm sorry if my initial example confused you.

daffl commented 4 months ago

Looks like it's one of the odd and mysterious TypeScript quirks. This appears to work:

import { JSONSchema } from 'json-schema-to-ts'
import { PropertyQuery, schema, Infer } from '@feathersjs/schema'

const queryPropertyWrapper = <T extends JSONSchema>(schema: T) => schema as PropertyQuery<T, unknown>

const testSchema = schema({
  $id: 'something',
  type: 'object',
  properties: {
    name: queryPropertyWrapper({ type: 'string' })
  }
} as const)

type Test = Infer<typeof testSchema>
desudo commented 4 months ago

This helped quite a lot. Thank you for your patience and time :)