打字稿扩展类型与接口

时间:2021-06-12 00:07:47

标签: javascript typescript

这可能是一个相对菜鸟的问题, 我有一个界面

interface Employee {
   name: string
}

并且我希望在将其保存到数据库后有一个扩展版本:

interface EmployeeDb {
   id: string,
   name: string
}

我想在处理检查时区分它,所以在我的存储中保存数据后,类型检查器不会抱怨没有 id 值。意思是我想避免使用这个:

interface Employee {
   id?: string,
   name: string
}

所以我不必到处检查 id。

所以我想这样做:

type Employee = {
   name: string
}

type IDatabaseObject<T> = {
  id: IDatabaseObjectId;
  [P in keyof T]: T[P];
};

type EmployeeDb = IDatabaseObject<Employee>

IDE 使用 top 语法给出错误

<块引用>

计算属性名称的类型必须为“字符串”、“数字”、“符号”、 或“任何”.ts(2464)

所以我尝试使用接口并扩展它

interface IDatabaseObject { 
   id: string
}

interface EmployeeDb extends Employee, IDatabaseObject {}

但是在后端代码中,当我尝试使用此设置时,我再次收到来自 vscode eslint 的错误。我这里有一个小代码,将数据添加到 localstorage,生成一个 id 并返回数据。见代码:

class DbAsyncStorageTemplate<
    InputDataType,
    OutputDataType extends IDatabaseObject
> {

    async addEntry(object: InputDataType): Promise<OutputDataType> {

        const id: string = generateUuid()
        const dbObject = { id, ...object }
        dbObject.id = id

        // add the item to AsyncStorage directly
        await AsyncStorage.setItem(id, JSON.stringify(object))

        // ERROR HERE: return the new object
        return dbObject as OutputDataType
    } 
    }
}

但我从 IDE (eslint) 收到最后一行的错误

<块引用>

'{ id: string; 类型的转换} & InputDataType' 输入 'OutputDataType' 可能是一个错误,因为这两种类型都不够 与另一个重叠。如果这是故意的,请转换 首先表达为“未知”。 '{ id: 字符串; } & InputDataType' 是 可分配给“OutputDataType”类型的约束,但 “OutputDataType”可以用不同的子类型实例化 约束“任何”。

有关如何正确执行此操作的任何建议?

1 个答案:

答案 0 :(得分:0)

我相信您正在寻找intersections of types

type Employee = {
   name: string
}

type EmployeeDb = {
  id: string;
} & Employee;

您还可以定义原始数据库接口并根据需要使用 PickOmit 实用程序。

Pick Utility

interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

type TodoPreview = Pick<Todo, "title" | "completed">;

const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
};