首页 > 解决方案 > 类型“{}”上不存在属性“title”。TS2339

问题描述

我正在从 JavaScript 切换到 TypeScript,一切都很顺利,直到我进入这种情况。我以这种方式设置我的界面:

interface StreamCreateProps {
  [title: string]: any 
};

我的代码是:

const validate = (formValues: any) => {
  const errors = {};

  if(!formValues.title) {
    errors.title = 'You must enter a title';
  };

  if(!formValues.description) {
    errors.description = 'You must enter a description';
  };

  return errors;
};

如何正确输入 errors.title 和 errors.description?完整的错误是:类型“{}”上不存在属性“标题”。

标签: typescript

解决方案


使用Record实用程序类型:

const errors: Record<string, string> = {};
errors.foo = 'okay';

当你声明一个变量而不指定类型时,你会导致 TypeScript 编译器为你推断它的类型。编译器将选择一个相当窄的类型。几个例子:

const foo = false // false
foo = true // ERROR
// `foo` is constant, so TS infers `false`, the only possible value. 

let foo = false // boolean
foo = true // OK
foo = 100 // ERROR
// Using `let` or `var` will result in `foo` being reassignable, 
//   so it could technically be anything; 
//   however, TS assumes a narrower type based on its initial value. 

// `foo` is constant, but it's properties are not, 
//   so, like with the previous row, `bar` is assignable to any boolean. 
const foo = { bar: false } // { bar: boolean; } 
foo.bar = true // OK
foo.bar = 100 // ERROR

// a `const` litteral declaration: 
//   foo and its subproperties should retain the narrowest possible type.
const foo = { bar: false } as const // { readonly bar: false; }
foo.bar = false // ERROR

所以适用于你的情况:

const foo = {} // {}
foo.bar = 'baz' // ERROR: Property 'bar' does not exist on type '{}'

foo太窄,无法接受其他属性。Record<string, string>限制较少:它确保您保留类似{ [key: string]: string }. 如果您需要使用非字符串值,您可以进一步扩展它:Record<string, string | number>Record<string, any>.

例子


推荐阅读