Reputation: 87
I have a complex object which shows:
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'
},
}
I tried to wrote like this:
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>
}
I can not continue writing IStyle
...
Apparently I cannot refer the type parameter T in IPosition with Cursor.
I am a new bee with typescript.
I want to practice writing precise typings
and don not want to use any
to bypass it.But I can not really figure out a better way for this.
Hope anyone may give me some suggestions.
Thx.
Upvotes: 0
Views: 123
Reputation: 14007
You are trying to pass a value of a property as a type parameter. That's not quite what the type system is made for. The types specify what possible values a property can have (and yes, you can restrict to specific string values); they are not designed to specify specific values.
Another problem is the mixture of a specified property with a mapped type. In this case the additional property must be of the same type as the mapped property. The solution is to specify the properties individually.
You can define these types to fully type your data structure:
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;
}
Upvotes: 1