diff --git a/src/abc.ts b/src/abc.ts new file mode 100644 index 0000000..33274dc --- /dev/null +++ b/src/abc.ts @@ -0,0 +1,16 @@ +import { + getFirelord, + MetaTypeCreator, + getFirestore, + query, + orderBy, + where, +} from './index' + +type A = MetaTypeCreator<{ a: number; b: string }, 'A'> + +const a = getFirelord(getFirestore(), 'A') + +const q1 = query(a.collection(), where('a', '==', 1), orderBy('b')) + +const q2 = query(a.collection(), orderBy('b'), where('a', '==', 1)) diff --git a/src/tests/discriminatedUnion.test.ts b/src/tests/discriminatedUnion.test.ts index ac96885..0c7867a 100644 --- a/src/tests/discriminatedUnion.test.ts +++ b/src/tests/discriminatedUnion.test.ts @@ -11,7 +11,8 @@ type DU = MetaTypeCreator< | { a: { b: 1; c: 2 } | { b: 'a'; d: 'b' } } | { x: { y: 1; z: 2; u: 3 } | { y: 'a'; w: 'b'; v: 'c' } | false } | { c: false } - | { c: true; v: 0 }, + | { c: true; v: 0 } + | Record }>, 'abc' > @@ -73,9 +74,17 @@ describe('test discrimination unions', () => { v: 'c', }, } - // should be error because no const assertion but ok + // should be error because no const assertion, not an ok behavior but expected // @ts-expect-error updateDoc(docRef, data) + + updateDoc(docRef, { random: { k: { '1': 1, '2': 2 } } }) + + const a = { m: '1' as '1' | '2' | '3' } + + const b = a.m + + updateDoc(docRef, { random: { k: { [b]: 1 } } }) } }) diff --git a/src/types/exactOptional.ts b/src/types/exactOptional.ts index 4b5cbe4..ff73c21 100644 --- a/src/types/exactOptional.ts +++ b/src/types/exactOptional.ts @@ -63,6 +63,54 @@ type ExactOptionalArray = T extends (infer ElementOfBase)[] : HandleUnknownMember : T +type ExceptOptionalSub< + T extends Record, + K, + Data, + Merge extends boolean | string[], // this is for set merge operation only + NoFlatten extends boolean, + TopLevel extends boolean +> = DeepValue extends infer S + ? unknown extends S + ? ErrorKeyNotExist + : S[] extends (infer BaseKeyElement)[][] | ArrayUnionOrRemove[] + ? Data[K & keyof Data] extends (infer DataKeyElement)[] + ? Data[K & keyof Data] extends never[] // https://stackoverflow.com/questions/71193522/typescript-inferred-never-is-not-never + ? DeepPartialExceptArray + : DataKeyElement extends BaseKeyElement + ? ExactOptionalArray[] + : BaseKeyElement[] + : IsSetDeleteAbleFieldValueValid< + S, + Data[K & keyof Data], + K & string, + Merge + > + : S extends Record + ? Data[K & keyof Data] extends infer R + ? R extends Record + ? ExactOptional + : DeepPartialExceptArray + : never + : Data[K & keyof Data] extends Delete + ? NoFlatten extends true + ? TopLevel extends false + ? ErrorNonTopLevelDeleteField + : IsSetDeleteAbleFieldValueValid< + S, + Data[K & keyof Data], + K & string, + Merge + > + : IsSetDeleteAbleFieldValueValid< + S, + Data[K & keyof Data], + K & string, + Merge + > + : IsSetDeleteAbleFieldValueValid + : T[K & keyof T] + // type checking for non-array in update operation export type ExactOptional< T extends Record, @@ -84,38 +132,9 @@ export type ExactOptional< : keyof Data extends (string extends keyof T ? string | number : keyof T) ? { [K in keyof T]?: K extends keyof Data - ? DeepValue extends infer S - ? unknown extends S - ? ErrorKeyNotExist - : S[] extends - | (infer BaseKeyElement)[][] - | ArrayUnionOrRemove[] - ? Data[K] extends (infer DataKeyElement)[] - ? Data[K] extends never[] // https://stackoverflow.com/questions/71193522/typescript-inferred-never-is-not-never - ? DeepPartialExceptArray - : DataKeyElement extends BaseKeyElement - ? ExactOptionalArray[] - : BaseKeyElement[] - : IsSetDeleteAbleFieldValueValid - : S extends Record - ? Data[K] extends infer R - ? R extends Record - ? ExactOptional - : DeepPartialExceptArray - : never - : Data[K] extends Delete - ? NoFlatten extends true - ? TopLevel extends false - ? ErrorNonTopLevelDeleteField - : IsSetDeleteAbleFieldValueValid< - S, - Data[K], - K & string, - Merge - > - : IsSetDeleteAbleFieldValueValid - : IsSetDeleteAbleFieldValueValid - : T[K] + ? ExceptOptionalSub + : string extends K + ? ExceptOptionalSub : T[K] } : HandleUnknownMember, Data>