假设我们有这样的界面:
interface Person {
name: string;
age: number;
}
我想调用Readonly并创建一个只读版本的接口,例如
interface PersonReadonly extends Readonly<Person> {}
这相当于写作
interface PersonReadonly {
readonly name: string;
readonly age: number;
}
我们可以编写这样的Readonly通用接口,还是已经编写过?
答案 0 :(得分:3)
回答你明确的问题:你在技术上不能做你想做的事。
类型映射将创建Type
而非界面 - Readonly<T>
是内置类型映射器,将返回Type
。您无法实现或扩展Type
别名,只能使用接口/类。
因此:
interface PersonReadonly extends Readonly<Person> {}
如果有support for implementing types are done,无效。
这并不能阻止你绕过Type;并且您可以在类型上使用union来构建更复杂的类型。因此你可以这样做:
type PersonWithState = Readonly<Person> & { state: string }
let person = <Person>{ name: "John", age: 20 };
let personState = <PersonWithState>{ ...person, state: "online" };
personState.age = "30"; // error;
personState.state = "offline"; // OK.
但是你不能拥有类实现或接口扩展PersonWithState
。
答案 1 :(得分:3)
你可以这样做:
type PersonReadonly = Readonly<Person>
但它不是一个界面。例如,您无法在其他位置添加新成员。
2017年5月编辑:自TS 2.2(2017年2月)起,interfaces can be derived from types。
答案 2 :(得分:2)
在游乐场中,Readonly
类型已定义,您可以执行以下操作:
interface Person {
name: string;
age: number;
}
let a: Readonly<Person> = {
name: "name",
age: 3
};
a.age = 5; // Error: Cannot assign to 'age' because it is a constant or a read-only property
如果在您的环境中定义了类型,那么您只需添加它:
type Readonly<T> = {
readonly [P in keyof T]: T[P];
}
但它要求你有打字稿2.1及以上。
如果你没有它,可能意味着你的打字稿版本低于2.1,否则你可以使用它。
答案 3 :(得分:1)
从TypeScript 2.1开始,用于创建实例readonly
的所有字段的通用接口。
它的确称为Readonly<T>
,因此您可以像这样使用它:
let person: Readonly<Person> = { name: 'John', age: 30 };
person.age = 31; // gives error
在TypeScript 2.1之前实现通用只读类型是不可能的。