Help with proper types (values)

I've been working to try to get a dynamic method to related/unrelate records together on a join table


async linkEntities<TJoinTable extends Table>(
        joinTable: TJoinTable,
        sourceIdField: keyof TJoinTable,
        relatedEntityField: keyof TJoinTable,
        sourceId: string,
        relatedEntityIds: string[],
    ) {
        // 1. Fetch existing related entity IDs

        const column = joinTable[sourceIdField] as Column // required to cast to satisfy where/eq

        type ExpectedRowType = {
            // maps over keys in the join table to be string or null
            [K in keyof TJoinTable]: string | null
        }

        const existingRelatedEntities = (await this.db
            .select()
            .from(joinTable)
            .where(eq(column, sourceId))) as ExpectedRowType[] // to get existingIds to work

        const existingIds = existingRelatedEntities.map(
            row => row[relatedEntityField],
        )
        // 2. Diff to get to-be-deleted and to-be-added IDs
        const toBeDeleted = existingIds.filter(
            id => id !== null && !relatedEntityIds.includes(id), // check if null should be included??
        )
    
        const toBeAdded = relatedEntityIds.filter(
            id => !existingIds.includes(id),
        )

        // 3. Delete old relations
        
        await this.db.transaction(async tx => {
            if (toBeDeleted.length) {
                ...
            }
            if (toBeAdded.length) {
                const payload: Record<string, string>[] = toBeAdded.map(id => ({
                    [sourceIdField]: sourceId,
                    [relatedEntityField]: id,
                }))
                const insertedRecords = await tx
                    .insert(joinTable)
                    .values(payload) // TODO: proper type?
                    .returning()

            }
        })
    }
image.png
Was this page helpful?