nic*_*ojs 6 typescript mapped-types
在 TypeScript 中,私有属性被视为类型的形状(或接口)的一部分。
class Person {
constructor(private name: string, public age: number) { }
}
const p: Person = { age: 42 };
// Error: Property 'name' is missing.
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为 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!
}
}
Run Code Online (Sandbox Code Playgroud)
但是,通常您想忽略私有接口。例如,当您使用依赖项注入和单元测试时。
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);
});
});
Run Code Online (Sandbox Code Playgroud)
我知道我们可以通过添加一个描述IHttpClient公共接口的接口来解决这个问题,HttpClient并直接使用它而不是类类型,但这需要大量的工作,并且需要手动保持同步。
有没有办法使用映射类型从类型中删除所有非公共属性?
就像是:
type PublicInterface<T> = {
[P in PublicNames<T>]: T[P];
}
Run Code Online (Sandbox Code Playgroud)
所以它可以用在你不关心隐私的地方:
class MyService {
constructor(private http: PublicInterface<HttpClient>) {
}
// Implementation
}
Run Code Online (Sandbox Code Playgroud)
Ale*_* L. 10
keyof足够聪明,只能查看公钥:
class Person {
constructor(private name: string, public age: number) { }
}
type PublicInterface<T> = {
[P in keyof T]: T[P];
}
const p: PublicInterface<Person> = { age: 42 }; // no error
Run Code Online (Sandbox Code Playgroud)
或者使用Pick实用程序甚至更短(结果相当于上面的映射类型):
type PublicInterface<T> = Pick<T, keyof T>;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1945 次 |
| 最近记录: |