将变量类型声明为接口的属性有什么用处(在typescript中)

vlf7wbxs  于 2022-12-14  发布在  TypeScript
关注(0)|答案(3)|浏览(169)

我是一个打字员新手,我想了解下面代码的用处,在这段代码中我创建了Person接口。
然后,我创建了一个人john。这部分很有意义。我们定义了一个接口,然后我们创建了一个符合预定义接口的变量。我可以看到这是有用的。
然而,在最后一行中,我们将类型设置为Person接口的name属性。我在野外看到过类似的代码,但我无法理解到底发生了什么。
这和直接说:let me: string = "karl"

interface Person {
  name: string;
  hungry: boolean;
}

let john: Person = {
    name: "john",
    hungry: false
}

let me: Person["name"] = "karl"
6mw9ycah

6mw9ycah1#

对于问题中的代码-你是对的,它没有多大意义。Person["name"]string相比是不必要的迟钝。
也就是说,如果您处理的是更复杂的对象,例如

interface Person {
  name: string;
  hungry: boolean;
  someProp: {
    subProp1: number;
    subProp2: string;
    subProp3: Array<string>
  }
}

假设您需要subProp的类型,那么您可以使用Person["someProp"],这比再次列出嵌套对象的完整类型要少得多。

const somePropToAssignToPerson: Person["someProp"] = {
  subProp1: 5,
  subProp2: 'foo',
  subProp3: ['bar']
};

可以说比

const somePropToAssignToPerson: {
  subProp1: number;
  subProp2: string;
  subProp3: Array<string>
} = {
  subProp1: 5,
  subProp2: 'foo',
  subProp3: ['bar']
};

也就是说,请注意,在您遇到的绝大多数情况下,这种刻意的注解都是不必要的。

let me = "karl"

将使TypeScript正确地将其推断为string,并且

const somePropToAssignToPerson = {
  subProp1: 5,
  subProp2: 'foo',
  subProp3: ['bar']
};

也会导致自动推断对象类型。(如果在声明这样的对象时出错,则在尝试将其赋给.someProp时,TypeScript将引发错误)

9gm1akwq

9gm1akwq2#

如果你想把Person["name"]的类型从string改为其他类型(例如type Name = {given: string; family: string}),那么你只需要在一个地方修改它,你会记得更新me变量,而不是保留me: string,这可能是不希望的。它告诉读者变量me将像人名一样使用。
同样地,也可以写

type Name = string;
interface Person {
  name: Name;
  hungry: boolean;
}

let john: Person = {
    name: "john",
    hungry: false,
};

let me: Name = "karl";

其中Person-names类型已经有了一个显式的名称。有时候,单独的名称没有太大的好处,引用类型Person["name"]和引用类型PersonName一样有意义。

mctunoxg

mctunoxg3#

在许多情况下,以这种方式宣告型别可能不是最佳作法。
正如其他人提到的,一个优点是,如果你在一个地方(接口)更改它,它也会在下面的对象中更改。
但是,缺点是您会使用不必要的类型定义来膨胀代码。
例如,如果您已经创建了Person界面,并且您标记了name:字符串,您不必总是担心提及类型。
如果你想创建一个新的人,使它像:

let person: Person = {
    name: "John",
    hungry: true,
}

现在,如果您需要获取名称,例如,执行以下操作

let name = person.name;

默认情况下,TypeScript知道name是String。您不必指定let name: stringlet name: Person["name"]。它只会增加额外的复杂性,这对您没有任何帮助,并会使您的代码更难读和理解。
声明一个接口的关键是声明对象将包含的数据类型。你不应该在任何地方都不断地定义它。
记住,如果你使用let test = "something",typescript知道这是一个字符串。你不需要总是定义类型,只需要在需要的地方定义:)

相关问题