您可以按如下方式修改输出类型(请注意函数签名):
type Person = {
id: string;
name: string;
age: number;
};
function excludeYoungPersons(person: readonly Person[]): ReadonlyArray<Readonly<Person>> {
let data = [...person];
const result = data.filter(item => item.age > 30)
return result;
}
const input: Person[] = [{
id: "xyz",
name: "Mary",
age: 32
}]
const result = excludeYoungPersons(input);
result[0] = { id: "nmp", name: "John", age: 41 }; //error
result[0].id = "rst"; //error!
也就是说,通过使用ReadonlyArray
,您将返回一个将数组限制为任何非 destruct 性数组的接口.然后,对于Readonly<Person>
,您将按原样考虑实际类型:
type Person = {
readonly id: string;
readonly name: string;
readonly age: number;
};
请记住,这是编译类型判断.如果你需要更强大的东西,你最好转向一个类,而不是POJO(简单-旧的脚本对象).
编辑:如果您只需要一个字段为只读,您可以这样写:
type TResultPerson =
Omit<Person, "id"> & {
readonly id: string;
}
function excludeYoungPersons(person: readonly Person[]): ReadonlyArray<TResultPerson> {
// (same as original)
}
下面是它的行为:
const result = excludeYoungPersons(input);
result[0] = { id: "nmp", name: "John", age: 41 }; //error
result[0].id = "rst"; //error!
result[0].name = "George"; //OK
编辑:正如@Darryl Noake在下面的 comments 中指出的那样,如果你需要在许多地方解决问题,还有另一个解决方案可以变得有用.
您可以在代码中的某个位置定义此帮助器:
type SemiReadonly<T, K extends keyof T> = Omit<T, K> & Readonly<Pick<T, K>>;
这基本上完全按照您的要求进行,但方式更加灵活.因此,为了将只读设置为"id"字段:
function excludeYoungPersons(person: readonly Person[]): SemiReadonlyArray<Person, "id"> {
// (same as original)
}
如果您也希望将只读设置为"name"字段:
function excludeYoungPersons(person: readonly Person[]): SemiReadonlyArray<Person, "id" | "name"> {
// (same as original)
}