typescript - 为什么我收到错误 "Object literal may only specify known properties"?

标签 typescript

我刚从 TypeScript 1.5 升级到最新版本,我在我的代码中看到一个错误:

interface Options {
   /* ... others ... */
   callbackOnLocationHash?: boolean;
}

function f(opts: Options) { /* ... */ }

//  Error: Object literal may only specify known properties,
//     and 'callbackOnLoactionHash'does not exist in type 'Options'.
f( { callbackOnLoactionHash: false });

我觉得代码很好。怎么了?

(另类宇宙版本:我知道错别字,我确实是故意写的。我应该怎么做才能消除错误?)

最佳答案

从 TypeScript 1.6 开始,对象字面量中的属性如果在它们被分配到的类型中没有对应的属性,则会被标记为错误。

通常此错误表示您的代码或定义文件中存在错误(通常是拼写错误)。在这种情况下,正确的解决方法是修复拼写错误。在问题中,属性 callbackOnLoactionHash不正确,应该是 callbackOnLocationHash (注意“位置”的拼写错误)。

此更改还需要对定义文件进行一些更新,因此您应该为正在使用的任何库获取最新版本的 .d.ts。

例子:

interface TextOptions {
    alignment?: string;
    color?: string;
    padding?: number;
}
function drawText(opts: TextOptions) { ... }
drawText({ align: 'center' }); // Error, no property 'align' in 'TextOptions'

但我本来打算那样做的

在某些情况下,您可能打算在对象中添加额外的属性。根据您正在做的事情,有几个适当的修复

仅对某些属性进行类型检查

有时您想确保一些东西存在并且类型正确,但出于某种原因想要拥有额外的属性。类型断言(<T>vv as T)不检查额外属性,因此您可以使用它们代替类型注释:

interface Options {
    x?: string;
    y?: number;
}

// Error, no property 'z' in 'Options'
let q1: Options = { x: 'foo', y: 32, z: 100 };
// OK
let q2 = { x: 'foo', y: 32, z: 100 } as Options;
// Still an error (good):
let q3 = { x: 100, y: 32, z: 100 } as Options;

这些属性,也许还有更多

一些 API 获取一个对象并动态迭代其键,但具有需要属于特定类型的“特殊”键。向类型添加字符串索引器将禁用额外的属性检查

之前

interface Model {
  name: string;
}
function createModel(x: Model) { ... }

// Error
createModel({name: 'hello', length: 100});

之后

interface Model {
  name: string;
  [others: string]: any;
}
function createModel(x: Model) { ... }

// OK
createModel({name: 'hello', length: 100});

这是狗还是猫还是马,还不确定

interface Animal { move; }
interface Dog extends Animal { woof; }
interface Cat extends Animal { meow; }
interface Horse extends Animal { neigh; }

let x: Animal;
if(...) {
  x = { move: 'doggy paddle', woof: 'bark' };
} else if(...) {
  x = { move: 'catwalk', meow: 'mrar' };
} else {
  x = { move: 'gallop', neigh: 'wilbur' };
}

这里想到了两个很好的解决方案

x 指定闭集

// Removes all errors
let x: Dog|Cat|Horse;

键入断言每件事

// For each initialization
  x = { move: 'doggy paddle', woof: 'bark' } as Dog;

这种时开时开

使用交集类型解决“数据模型”问题的干净方法:

interface DataModelOptions {
  name?: string;
  id?: number;
}
interface UserProperties {
  [key: string]: any;
}
function createDataModel(model: DataModelOptions & UserProperties) {
 /* ... */
}
// findDataModel can only look up by name or id
function findDataModel(model: DataModelOptions) {
 /* ... */
}
// OK
createDataModel({name: 'my model', favoriteAnimal: 'cat' });
// Error, 'ID' is not correct (should be 'id')
findDataModel({ ID: 32 });

另见 https://github.com/Microsoft/TypeScript/issues/3755

关于typescript - 为什么我收到错误 "Object literal may only specify known properties"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31816061/

相关文章:

javascript - 为什么我不能使用 SystemJS 直接从 node_modules 导入?

c# - Angular 2 Http 删除 header 以便与 Web API REST 一起使用

javascript - Angular使用javascript函数

Typescript:获取类型的第一个属性的类型

javascript - 我的 Electron 应用程序在没有任何日志记录的情况下无法启动

angular - Rxjs无法获取过去的值

javascript - 在 monorepo 中共享 typescript 库

angular - 具有自定义列的自定义 Angular 6 Material 表组件

html - 需要帮助找到在数据表中应用 css 样式的正确位置

node.js - 处理ExpressJS中混合的同步和异步错误的最佳方法