如何理解打字稿中的“属性'名称'在'用户'类型中是私有的”

Posted

技术标签:

【中文标题】如何理解打字稿中的“属性\'名称\'在\'用户\'类型中是私有的”【英文标题】:How to understand "Property 'name' is private in type 'User'" in typescript如何理解打字稿中的“属性'名称'在'用户'类型中是私有的” 【发布时间】:2020-08-31 01:54:29 【问题描述】:

我定义了一个类User,它有一个私有字段:

class User 
  private name: string = 'name'
  hello(): void 

  

一个函数使用User类型:

function testUser(user: User) 

我不想创建User 的实例,而是想使用一个对象来模拟它:

testUser(
  name: 'new-name',
  hello: () => 
)

但是它有一个编译错误:

Argument of type ' name: string; hello: () => void; ' is not assignable to parameter of type 'User'.
  Property 'name' is private in type 'User' but not in type ' name: string; hello: () => void; '.(2345)

我不明白:

    nameUser 类中是私有的,为什么我们必须在我的模拟对象中提供它? 是否可以在模拟对象中提供private 'name',或者找到不提供它而不会出现编译错误的方法?

Living demo in playground

【问题讨论】:

我认为你不应该提供它,它在抱怨,因为你是...... 【参考方案1】:

在尝试将对象字面量分配给期望类的位置时,私有字段有点问题。 Typescript 的立场是,由于私有字段是只有声明类才能修改的东西,所以它不应该是可别名的。

你只能通过类型断言来解决这个问题。您可以创建一个创建类模拟的函数,方法是只接受类的公共字段并在内部进行类型断言,以确保类型断言不会隐藏其他错误。只选择公共字段的方法是通过Pick<T, keyof T> 传递类型。由于keyof T 仅公开公共属性,因此您最终会删除私有属性:


function mock<T>(o: Pick<T, keyof T>): T 
  return o;


testUser(mock<User>(
  hello: () => 

  
))

Playground Link

【讨论】:

以上是关于如何理解打字稿中的“属性'名称'在'用户'类型中是私有的”的主要内容,如果未能解决你的问题,请参考以下文章

如何覆盖打字稿中的属性?

打字稿中的Angular js Http承诺

如何访问打字稿中的字段验证错误?

如何从打字稿中的json响应中获取日期对象

如何使用打字稿中的反应钩子设置graphql数据?

如何从打字稿中的标记联合类型中提取类型?