首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >错误TS2339:类型'Y‘上不存在属性'x’

错误TS2339:类型'Y‘上不存在属性'x’
EN

Stack Overflow用户
提问于 2016-07-12 17:29:31
回答 8查看 221.6K关注 0票数 81

我不明白为什么这段代码会产生TypeScript错误。(这不是原始代码,有点派生出来的,所以请忽略示例中的无意义):

代码语言:javascript
复制
interface Images {
  [key:string]: string;
}

function getMainImageUrl(images: Images): string {
  return images.main;
}

我遇到错误(使用TypeScript 1.7.5):

错误TS2339:类型“”Images“”上不存在属性“”main“”。“

当然,我可以在编写代码时消除这个错误:

代码语言:javascript
复制
return images["main"];

我不喜欢使用字符串来访问这个属性。我能做什么?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2016-07-12 17:50:47

如果您希望能够访问images.main,则必须对其进行显式定义:

代码语言:javascript
复制
interface Images {
    main: string;
    [key:string]: string;
}

function getMainImageUrl(images: Images): string {
    return images.main;
}

不能使用点表示法访问索引属性,因为typescript无法知道对象是否具有该属性。

然而,当你专门定义一个属性时,编译器就知道它存在(或不存在),无论它是可选的还是非可选的,以及它的类型是什么。

编辑

您可以为地图实例创建一个帮助器类,如下所示:

代码语言:javascript
复制
class Map<T> {
    private items: { [key: string]: T };

    public constructor() {
        this.items = Object.create(null);
    }

    public set(key: string, value: T): void {
        this.items[key] = value;
    }

    public get(key: string): T {
        return this.items[key];
    }

    public remove(key: string): T {
        let value = this.get(key);
        delete this.items[key];
        return value;
    }
}

function getMainImageUrl(images: Map<string>): string {
    return images.get("main");
}

我已经实现了类似的东西,我发现它非常有用。

票数 54
EN

Stack Overflow用户

发布于 2017-07-11 00:23:46

正确的修复方法是在类型定义中添加属性,如@Nitzan Tomer的答案所述。如果这不是一个选择,那么:

(Hacky)解决方法1

您可以将对象赋给类型为any的常量,然后调用“non-existing”属性。

代码语言:javascript
复制
const newObj: any = oldObj;
return newObj.someProperty;

也可以将其强制转换为any

代码语言:javascript
复制
return (oldObj as any).someProperty;

但是,这并没有提供任何类型安全性,而这正是TypeScript的要点。

(Hacky)解决方法2

如果不能修改原始类型,您可以考虑的另一件事是扩展类型,如下所示:

代码语言:javascript
复制
interface NewType extends OldType {
  someProperty: string;
}

现在,您可以将变量转换为此NewType而不是any。仍然不是很理想,但没有any那么宽松,它提供了更多的类型安全性。

代码语言:javascript
复制
return (oldObj as NewType).someProperty;
票数 34
EN

Stack Overflow用户

发布于 2016-07-12 17:51:12

我不是打字专家,但我认为主要的问题是访问数据的方式。看到您是如何描述Images接口的,您可以将任何键定义为字符串。

当访问一个属性时,“点”语法(images.main)假设它已经存在。我在没有Typescript的情况下遇到了这样的问题,在"vanilla“Javascript中,我试图访问以下数据:

return json.property[0].index

其中index是一个变量。但它解释了index,结果是:

cannot find property "index" of json.property[0]

我必须找到一个使用你的语法的变通方法:

return json.property[0][index]

这可能是你唯一的选择。但是,再说一次,我不是Typescript专家,如果有人知道发生了什么事情的更好的解决方案/解释,请随时纠正我。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38324949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档