如何将"对象"替换为"记录<字符串,未知>"?



考虑一下:

interface Foo {
foo: string;
}
const foo: Foo = { foo: "foo" };
function bar(obj: object) {}                   // <--- ERROR 1
bar(foo);
function baz(obj: Record<string, unknown>) {}
baz(foo);                                      // <--- ERROR 2

所以,ERROR 1是:

Don't use `object` as a type. The `object` type is currently hard to use ([see this issue](https://github.com/microsoft/TypeScript/issues/21732)).
Consider using `Record<string, unknown>` instead, as it allows you to more easily inspect and use the keys.eslint@typescript-eslint/ban-types

因此,我按照我被告知的做了,用baz中的Record<string, unknown>代替了object。但是,现在我得到ERROR 2:

Argument of type 'Foo' is not assignable to parameter of type 'Record<string, unknown>'.
Index signature for type 'string' is missing in type 'Foo'.ts(2345)

那么,避免使用object的正确方法是什么呢?

这是目前TypeScript的一个已知问题。

您应该将Foo更改为type而不是interface:

type Foo = {
foo: string
};
const foo: Foo = { foo: "foo" };
function baz(obj: Record<string, unknown>) {}
baz(foo);                   

编辑:如果你对接口没有任何控制权,你可以使用Younho Choo在前面提到的GitHub问题线程上创建的这个实用程序类型:

interface Foo {
foo: string;
}
type IndexSignature<O extends object> = {
[P in keyof O]: O[P]
};
const foo: IndexSignature<Foo> = { foo: "foo" };
function baz(obj: Record<string, unknown>) {}
baz(foo); 

这避免了使用any,一些开发人员认为这是不好的做法(尽管我认为在TmTron的回答中这是完全可以接受的做法)。

打印稿操场

当您使用Record<string, any>时,您不会得到错误。
请注意,对象值的类型是any而不是unknown:参见'unknown'和& # 39;任何# 39;

interface Foo {
foo: string;
}
const foo: Foo = { foo: "foo" };
function fct(obj: Record<string, any>) {}
fct(foo);

打印稿操场

最新更新