简体   繁体   English

从键中获取对象值的类型

[英]Getting type of Object's value from key

I created a data.我创建了一个数据。

type PenType = {
    color: string
}

type PencilType = {
    darkness: string
}

const data: {
    pen: PenType,
    pencil: PencilType
} = {
    pen: {
        color: "blue",
    },
    pencil: {
        darkness: "2B"
    }
};

type DataKeys = keyof typeof data;

I now have Object data with keys and values.我现在有 Object 个带有键和值的数据。 I did create a function to get value from the data.我确实创建了一个 function 来从数据中获取价值。

type MyReturnType = PenType | PencilType;

const getMyData = (keyToGet: DataKeys): MyReturnType => {
    return data[keyToGet];
}

const finalData = getMyData('pen');

console.log(finalData);

This works completely fine.这完全没问题。 But the issue is, I want to get correct type in my finalData .但问题是,我想在我的finalData中获得正确的类型。 Since I have tried to access pen, I want return type to be PenType , not PenType | PencilType因为我尝试访问笔,所以我希望返回类型为PenType ,而不是PenType | PencilType PenType | PencilType

Is there any way to achieve this?有什么办法可以做到这一点?

Sandbox link: https://codesandbox.io/s/typescript-playground-export-forked-hnle7p?file=/index.ts沙盒链接: https://codesandbox.io/s/typescript-playground-export-forked-hnle7p?file=/index.ts

If you explicitly annotate the return type to be PenType | PencilType如果您显式地将返回类型注释PenType | PencilType PenType | PencilType , then that's what the function will return no matter what. PenType | PencilType ,那么这就是 function 无论如何都会返回的内容。

If, instead, you want the compiler to keep track of the literal type of the value passed in as keyToGet , you need getMyData() to be generic in that type, with a generic type parameter as follows:相反,如果您希望编译器跟踪作为keyToGet传入的值的文字类型,则需要getMyData()在该类型中是通用的,具有通用类型参数,如下所示:

const getMyData = <K extends DataKeys>(keyToGet: K) => {
    return data[keyToGet];
}

Here, getMyData is generic in K , a type parameter constrained to be assignable to DataKeys , and the type of the keytoGet function parameter.在这里, getMyDataK中是通用的,一个类型参数被限制为可分配给DataKeys ,以及keytoGet function 参数的类型。

I didn't annotate the return type explicitly.我没有明确注释返回类型。 Instead, performing the indexing operation data[keyToGet] and returning it means the returned type is inferred by the compiler to be a generic indexed access type :相反,执行索引操作data[keyToGet]并返回它意味着返回的类型被编译器推断为通用索引访问类型

/* {
    pen: PenType;
    pencil: PencilType;
}[K] */

So when you call getMyData('pen') , K is inferred as "pen" , and then the return type will be {pen: PenType; pencil: PencilType}["pen"]因此,当您调用getMyData('pen')时, K被推断为"pen" ,然后返回类型将为{pen: PenType; pencil: PencilType}["pen"] {pen: PenType; pencil: PencilType}["pen"] , an indexed access type that evaluates to PenType : {pen: PenType; pencil: PencilType}["pen"] ,一种计算结果为PenType的索引访问类型:

const finalData = getMyData('pen');
// const finalData: PenType

console.log(finalData.color.toUpperCase()); // "BLUE"

Playground link to code 游乐场代码链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM