如何为此类对象编写接口?

时间:2018-07-23 07:23:28

标签: typescript typescript-typings

我有一个复杂的对象,显示:

const styles = {
       base: {
           position: 'absolute',
           userSelect: 'none',
        //    backgroundColor: '#4323ba'
       },
       top: {
        width: '100%',
        height: '10px',
        top: '-5px',
        left: '0px',
        cursor: 'row-resize'
       },
       bottom: {
        width: '100%',
        height: '10px',
        bottom: '-5px',
        left: '0px',
        cursor: 'row-resize'
       },
       left: {
        width: '10px',
        height: '100%',
        left: '-5px',
        top: '0px',
        cursor: 'col-resize'
       },
       right: {
        height: '100%',
        width: '10px',
        right: '-5px',
        top: '0',
        cursor: 'col-resize'
       },
       topLeft: {
        width: '20px',
        height: '20px',
        top: '-10px',
        left: '-10px',
        cursor: 'nwse-resize'
       },
       topRight: {
        width: '20px',
        height: '20px',
        top: '-10px',
        right: '-10px',
        cursor: 'nesw-resize'
       },
       bottomLeft: {
        width: '20px',
        height: '20px',
        bottom: '-10px',
        left: '-10px',
        cursor: 'nesw-resize'
       },
       bottomRight: {
        width: '20px',
        height: '20px',
        bottom: '-10px',
        right: '-10px',
        cursor: 'nwse-resize'
       },
     }

我试图这样写:

interface IPosition<T> {
   width: string,
   height: string,
   cursor: Cursor[T]
}
enum Cursor {
top = 'row-resize',
bottom = 'row-resize',
left = 'col-resize',
right = 'col-resize',
topLeft = 'nwse-resize',
topRight = 'nesw-resize',
bottomLeft = 'nesw-resize',
bottomRight = 'nwse-resize'
   }
interface IStyle {
    base: object,
    [propName: string]: IPosition<propName>
}

我无法继续写IStyle ... 显然,我无法在IPosition with Cursor中引用类型参数T。 我是有打字稿的新蜜蜂。 我想练习编写精确的typings,并且不想使用any来绕过它。但是我无法真正找到一种更好的方法。 希望有人可以给我一些建议。 谢谢。

1 个答案:

答案 0 :(得分:1)

您试图将属性的值作为类型参数传递。这并不是类型系统的主要用途。这些类型指定属性可以具有的可能值(是的,您可以限制为特定的字符串值);它们并非旨在指定特定值。

另一个问题是指定属性与映射类型的混合。在这种情况下,附加属性必须与映射属性具有相同的类型。解决方案是分别指定属性。

您可以定义以下类型以完全键入数据结构:

enum Cursor {
    top = 'row-resize',
    bottom = 'row-resize',
    left = 'col-resize',
    right = 'col-resize',
    topLeft = 'nwse-resize',
    topRight = 'nesw-resize',
    bottomLeft = 'nesw-resize',
    bottomRight = 'nwse-resize'
}

interface Position {
   width: string;
   height: string;
   cursor: Cursor;
}

interface LeftPos {
    left: string;
}

interface RightPos {
    right: string;
}

interface TopPos {
    top: string;
}

interface BottomPos {
    bottom: string;
}

interface Style {
    base: { [key: string]: string };
    top: Position & TopPos;
    bottom: Position & BottomPos;
    left: Position & LeftPos;
    right: Position & RightPos;
    topLeft: Position & TopPos & LeftPos;
    topRight: Position & TopPos & RightPos;
    bottomLeft: Position & BottomPos & LeftPos;
    bottomRight: Position & BottomPos & RightPos;
}