使用 this.store.findRecod 时如何修复类型检查

How to fix type checking when using this.store.findRecod

在我的 ember.js 项目中,我使用 Typescript 和 checkJs 选项输入检查 javascript 文件。

这是一个简单的 route.js 文件示例

import Route from '@ember/routing/route';

export default class UsersRoute extends Route {
  model() {
    return this.store.findAll('user');
  }

}

使用此代码,我收到以下 Typescript 错误

route.js:5:31 - error TS2345: Argument of type '"user"' is not assignable to parameter of type 'never'.

5     return this.store.findAll('user');
                                ~~~~~~

ember-数据类型定义由@types/ember-data包提供,这里是findAll definition

findAll<K extends keyof ModelRegistry>(
    modelName: K,
    options?: {
        reload?: boolean;
        backgroundReload?: boolean;
        include?: string;
        adapterOptions?: any;
    }
): PromiseArray<ModelRegistry[K]>;

这是我在调查 findAll 的定义时可以走多远。

理论上,this.store.findAll('user');是有效的,但是我应该怎么做才能修复这个Typescript错误?

要了解正在发生的事情,我建议阅读 this section of the ember-cli-typescript docs。要点是为 Ember 提供的类型做了一些额外的工作,以便当您键入 this.findRecord('person', 1) 时,您得到的结果是 Person(例如 DS.Model 你已经定义了)。为了实现这一点,类型定义了一个 "registry"——字符串名称和类型到 return 之间的映射。 "registry" 为空是您在类型中看到的问题。

ember-cli-typescript 的默认配置使这个 "just work",通过在 tsconfig.json 中设置 paths 键来包含 "*": "types/*" 和将此文件包含在 <your app directory>/types/ember-data/types/registries/model.d.ts:

/**
 * Catch-all for ember-data.
 */
export default interface ModelRegistry {
  [key: string]: any;
}

只需将类型设置为 any.

,即可对模型 "work" 进行所有字符串查找

如果你想真正定义类型,你需要创建一个user.d.ts文件,紧挨着导出模型的user.js输入 and 其中包括:

declare module 'ember-data/types/registries/model' {
  export default interface ModelRegistry {
    'user': User;
  }
}

运行 ember generate ember-cli-typescript 如果您已经在使用它,它会为您更新这些内容。您还可以使用这些内容手动创建该文件并设置 paths 映射(并且您可能还想添加来自 the default blueprint 的其他路径映射)。