[Vuejs]-Typescript. Some object keys in array with foreach method and rewrite keys

1๐Ÿ‘

I think the affectation is not ok

task.value[key] = removeTemporaryIdFromArray<typeof key>(task.value[key] as TaskMaterial[]) as undefined;

because removeTemporaryIdFromArray can not choose between various types (TaskMaterial[] | TaskQuestion[] | TaskRole[] | TaskTable[] | undefined) when set task.value[key].

I think you can work around with removeTemporaryIdFromArray_InPlace.

Here is my proposal (little verbose may be), and it is difficult to test without context. But typescript say ok.

// helper type
type Writable<T> = { -readonly [K in keyof T]: T[K] };
// your properties to loop on
const KeyNames = ["materials", "questions", "roles", "tables"] as const;
// type helper with only the 'good' keys, never undefined (but we do not care.)
type SubPropertyTask = Required<Pick<Task, typeof KeyNames[number]>>;
// your properties to loop on transformed in an array of keys, that you can loop on really.
const WriteableKeyNames = KeyNames as Writable<typeof KeyNames> as Array<keyof SubPropertyTask>;

// your new submit
function handleSubmitV3() {
    // loop on key
    WriteableKeyNames.forEach((key: keyof SubPropertyTask) => {
        // the call wich is not so trivial
        // < type of first element of the array (because we know its array)
        // need also type of the key, taht can not be infered.
        removeTemporaryIdFromArrayInplace<SubPropertyTask[typeof key][0], typeof key>(task[key], key);
    });
}
// T might be written like this : T extends TaskQuestion | TaskMaterial | TaskRole | TaskTable
// but if you need to add other property, name should be enougth
export const removeTemporaryIdFromArrayInplace = <T, E extends keyof SubPropertyTask>(entity: Array<T> | undefined, e: E): void => {
    // do your own filter/
    const filteredEntity = entity?.filter((taskObject: T) => taskObject);

    // set up the new value, which would work, with this particlar cast.
    // Because at this time typeof task[e] is same as T and as  SubPropertyTask[E] | undefined
    // ... I think.
    task[e] = filteredEntity as SubPropertyTask[E] | undefined;
};

Leave a comment