首页 > 解决方案 > 当方法按预期工作时,为什么不能推断出正确的类型?

问题描述

这是 TS Playground 的链接,使用评论解释我的问题。我决定不将整个内容作为内联代码包含在内,因为我想防止不必要的滚动。

问题:
虽然该normalize方法按预期工作(如操场所示),但当使用泛型类型调用它时,它的结果不会根据传入的泛型类型值推断类型,而是联合所有可能的值。

我尝试过的:
我尝试玩type NormalizeFn,还留下了我在操场上尝试过的示例,但不仅没有奏效,还因为我输入错误而开始对我大喊大叫。

我正在尝试修复的方法:
注意:这只是游乐场链接中包含的内容的一部分

// Converts a Record<entity_id, entity_value_object>
// into Array<entity_value_object & {id: entity_id}>
// Basically moves the id as key into the value object so that 
// we add the id field back into the result that didn't have the id.
type NormalizeFn = <
    // i.e. I tried below and things similar to it, but it gives errors as I am not able to 
    // get it working without ts yelling at me.
    // ObjType extends Record<string, Record<string, any>>  | undefined = { id: Record<string, any> },
    ObjType extends object  | undefined = object,
    KeyId extends string = 'id'
>(
    obj: ObjType,
    keyPropName?: KeyId
) => ObjType extends Record<infer Key, infer Val>
    ? Array<Val & { [key in KeyId]: Key }>
    : never;

const normalize: NormalizeFn = (obj, keyPropName) => {
    return Object.entries(obj || {}).map(([key, val]) => {
        return {
            ...val,
            [keyPropName || 'id']: key,
        };
    });
};

一些测试展示了它是如何工作的:

// Normalize works as inteded:
const testFirestoreUserDataResult: FirestoreData['users'] = {
    user_id: {
        name: 'user_name'
    },
    user_id2: {
        name: 'user_name2'
    }
}

// Normalize tests showing its usage.
const normalizedUsers = normalize(testFirestoreUserDataResult);
normalizedUsers[0].id; // in VSCode this also infers 'user_id' | 'user_id2'
normalizedUsers[0].name;

const normalizedUsers2 = normalize(testFirestoreUserDataResult, 'customIdKey');
normalizedUsers2[0].id; // Fails as intended
normalizedUsers2[0].customIdKey; // in VSCode this also infers 'user_id' | 'user_id2'
normalizedUsers2[0].name;

问题1:有什么问题type NormalizeFn
问题2:可以type NormalizeFn改进/写得更好吗?

我确信我错过了一些简单且可能是基本的东西,但我就是无法让它发挥作用。希望有人可以在这里指导我,感谢您的帮助!

标签: typescripttypesinference

解决方案


推荐阅读