在TypeScript中,私有属性被视为类型的形状(或接口)的一部分。
因此,它可以在您不关心私密性的场所使用:
class Person {
constructor(private name: string, public age: number) { }
}
const p: Person = { age: 42 };
// Error: Property 'name' is missing.
这是有效的,因为TypeScript需要跟踪私有成员。
class Person {
constructor(private name: string, public age: number) { }
equals(other: Person) {
return this.name === other.name && this.age === other.age;
// This is valid, because TypeScript kept track of the private `name` property!
}
}
然而,通常情况下,您希望忽略私有接口。例如,在使用依赖注入和单元测试时。
class HttpClient {
constructor(private log: Logger) {
}
async doGet(url: string) {
return (await fetch(url)).json();
}
}
class MyService {
constructor(private http: HttpClient) {
}
// Implementation
}
// Unit test for MyService:
describe('MyService', () => {
it('should work', () => {
const httpMock: HttpClient = { // ERROR: Property 'log' is missing
doGet(url: string) {
return Promise.resolve({ name: 'Han' });
}
};
const sut = new MyService(httpMock);
});
});
我知道我们可以通过添加IHttpClient
接口来解决这个问题,该接口描述了HttpClient
的公共接口,并使用它代替直接使用类类型,但这需要很多工作,并且需要手动保持同步。
是否有一种使用映射类型从类型中删除所有非公共属性的方法?
类似于:
type PublicInterface<T> = {
[P in PublicNames<T>]: T[P];
}
因此,它可以在您不关心私密性的场所使用:
class MyService {
constructor(private http: PublicInterface<HttpClient>) {
}
// Implementation
}