从对象文字中查找打字稿

问题描述 投票:0回答:1

我在打字稿中有这样的对象文字:

const data={
  a:'valueOfA',
  b:'valueOfB,
  ...
}

然后,我需要通过传递对象和属性来更新位于不同位置的值,如下所示:

function update(obj,prop){
...
}
update(data,'a');

这当然可以,但是我想使用点表示法并利用IDE中的智能感知来访问该属性。所以我可以这样调用函数:

update(data,KeysOfData.a);

我做了一个效果很好的第一个实现,并提供了智能感知功能,但对我来说看起来很难看,我想知道是否有更好的方法来获得结果。这是当前的实现:

type FormProps = {
    firstName?: string,
    lastName?: string,
    email?: string
}

const formData: FormProps = {
    firstName: '',
    lastName: '',
    email: ''
}

type FormItemName = keyof FormProps;
type FormItem = {
    [key in FormItemName]: string
}

// Generates lookup object
const Fields: FormItem = Object.keys(formData).reduce<FormItem>((obj, field) => {
    obj[field as FormItemName] = field;
    return obj;
}, {} as any);


// Later call to update
update(formData,Fields.firstName);

typescript lookup object-literal
1个回答
0
投票

首先,我想指出“如何使此代码更干净/更好”被认为是不好的堆栈溢出问题,请参见How to Ask,以获取有关该主题的更多信息。

但是,考虑到您是一个新的贡献者,我将把这个问题视为询问如何使用泛型和keyof以使您的代码可重用并提高类型安全性的问题。如果您不适合此类别,我们深表歉意,并要求更好的答案。在哪种情况下,您只需编辑您的问题,以更精确地了解您希望实现的目标。


第一个建议:您的解决方案,但使用泛型

您可以提取实现,以便可以将其重用于其他对象,例如:

// Generic reusable lookup type
type FieldLookup<T> = { [key in keyof T]: string }

// Generic reusable lookup generation function
function generateFieldLookup<T>(data: T): FieldLookup<T> {
    return Object.keys(formData).reduce((obj, field) => {
        obj[field as keyof T] = field;
        return obj;
    }, {} as FieldLookup<T>)
}

// Generates lookup object
const Fields = generateFieldLookup(formData)


// Later call to update
update(formData, Fields.firstName);

但是,此类型表示T的属性也是查找对象的属性,该对象的值为一些字符串,更正确的类型为:

type FieldLookup<T> = { [key in keyof T]: key; }

function generateFieldLookup<T>(data: T): FieldLookup<T> {
    return Object.keys(formData).reduce((obj, field) => {
        const key = field as keyof T;
        obj[key] = key;
        return obj;
    }, {} as FieldLookup<T>)
}

现在,当您将鼠标悬停在Fields.firstName上时,您还将获得其类型的确切值。但是,可以说undefined是可能的。这是因为类型中没有任何地方表明所有字段都包含在查找中。

如果这在代码中的任何地方都给您带来了问题,请执行Fields.firstName!


第二个建议:类型update

[如果您可以牺牲IDE在单击点时向您提供建议的能力,并且只希望通过将函数悬停在函数上以得到推断的类型来输入安全性和建议,则可以取消整个实现,而只需键入更新为:

function update<T>(obj: T, prop: keyof T): void


// Later call to update
update(formData, 'firstName');

请注意,此建议确实将之前的建议排除在外,您可以同时使用两者。

如果这样做,您必须在第一个建议中使用实现的更高级版本,并带有感叹号,即:]]

// Generic reusable lookup type
type FieldLookup<T> = { [key in keyof T]: key }

function update<T>(obj: T, prop: keyof T): void

// Later call to update
update(formData, Fields.firstName!);
© www.soinside.com 2019 - 2024. All rights reserved.