diff --git a/src/mol-math/geometry/symmetry-operator.ts b/src/mol-math/geometry/symmetry-operator.ts
index 88d12323f27647b6921f9d827232f1746729c697..56377d0b5e48bee4b30f83f2b6f9702f00e962ac 100644
--- a/src/mol-math/geometry/symmetry-operator.ts
+++ b/src/mol-math/geometry/symmetry-operator.ts
@@ -58,11 +58,11 @@ namespace SymmetryOperator {
         return create(second.name, matrix, second.hkl);
     }
 
-    export interface CoordinateMapper { (index: number, slot: Vec3): Vec3 }
-    export interface ArrayMapping {
+    export interface CoordinateMapper<T extends number> { (index: T, slot: Vec3): Vec3 }
+    export interface ArrayMapping<T extends number> {
         readonly operator: SymmetryOperator,
-        readonly invariantPosition: CoordinateMapper,
-        readonly position: CoordinateMapper,
+        readonly invariantPosition: CoordinateMapper<T>,
+        readonly position: CoordinateMapper<T>,
         x(index: number): number,
         y(index: number): number,
         z(index: number): number,
@@ -71,14 +71,14 @@ namespace SymmetryOperator {
 
     export interface Coordinates { x: ArrayLike<number>, y: ArrayLike<number>, z: ArrayLike<number> }
 
-    export function createMapping(operator: SymmetryOperator, coords: Coordinates, radius: ((index: number) => number) | undefined): ArrayMapping {
+    export function createMapping<T extends number>(operator: SymmetryOperator, coords: Coordinates, radius: ((index: number) => number) | undefined): ArrayMapping<T> {
         const invariantPosition = SymmetryOperator.createCoordinateMapper(SymmetryOperator.Default, coords);
         const position = operator.isIdentity ? invariantPosition : SymmetryOperator.createCoordinateMapper(operator, coords);
         const { x, y, z } = createProjections(operator, coords);
         return { operator, invariantPosition, position, x, y, z, r: radius ? radius : _zeroRadius };
     }
 
-    export function createCoordinateMapper(t: SymmetryOperator, coords: Coordinates): CoordinateMapper {
+    export function createCoordinateMapper<T extends number>(t: SymmetryOperator, coords: Coordinates): CoordinateMapper<T> {
         if (t.isIdentity) return identityPosition(coords);
         return generalPosition(t, coords);
     }
@@ -145,7 +145,7 @@ function projectZ({ matrix: m }: SymmetryOperator, { x: xs, y: ys, z: zs }: Symm
     }
 }
 
-function identityPosition({ x, y, z }: SymmetryOperator.Coordinates): SymmetryOperator.CoordinateMapper {
+function identityPosition<T extends number>({ x, y, z }: SymmetryOperator.Coordinates): SymmetryOperator.CoordinateMapper<T> {
     return (i, s) => {
         s[0] = x[i];
         s[1] = y[i];
@@ -154,10 +154,10 @@ function identityPosition({ x, y, z }: SymmetryOperator.Coordinates): SymmetryOp
     }
 }
 
-function generalPosition({ matrix: m }: SymmetryOperator, { x: xs, y: ys, z: zs }: SymmetryOperator.Coordinates) {
+function generalPosition<T extends number>({ matrix: m }: SymmetryOperator, { x: xs, y: ys, z: zs }: SymmetryOperator.Coordinates) {
     if (isW1(m)) {
         // this should always be the case.
-        return (i: number, r: Vec3): Vec3 => {
+        return (i: T, r: Vec3): Vec3 => {
             const x = xs[i], y = ys[i], z = zs[i];
             r[0] = m[0] * x + m[4] * y + m[8] * z + m[12];
             r[1] = m[1] * x + m[5] * y + m[9] * z + m[13];
@@ -165,7 +165,7 @@ function generalPosition({ matrix: m }: SymmetryOperator, { x: xs, y: ys, z: zs
             return r;
         }
     }
-    return (i: number, r: Vec3): Vec3 => {
+    return (i: T, r: Vec3): Vec3 => {
         r[0] = xs[i];
         r[1] = ys[i];
         r[2] = zs[i];
diff --git a/src/mol-model/structure/structure/unit.ts b/src/mol-model/structure/structure/unit.ts
index a1cd1097eb667b89cd95b9597c9ef2338ef0d07c..933cd583a02d1194bbabb6ce241899d8e96d5554 100644
--- a/src/mol-model/structure/structure/unit.ts
+++ b/src/mol-model/structure/structure/unit.ts
@@ -94,7 +94,7 @@ namespace Unit {
         readonly invariantId: number,
         readonly elements: StructureElement.Set,
         readonly model: Model,
-        readonly conformation: SymmetryOperator.ArrayMapping,
+        readonly conformation: SymmetryOperator.ArrayMapping<ElementIndex>,
 
         getChild(elements: StructureElement.Set): Unit,
         applyOperator(id: number, operator: SymmetryOperator, dontCompose?: boolean /* = false */): Unit,
@@ -128,7 +128,7 @@ namespace Unit {
         readonly invariantId: number;
         readonly elements: StructureElement.Set;
         readonly model: Model;
-        readonly conformation: SymmetryOperator.ArrayMapping;
+        readonly conformation: SymmetryOperator.ArrayMapping<ElementIndex>;
 
         // Reference some commonly accessed things for faster access.
         readonly residueIndex: ArrayLike<ResidueIndex>;
@@ -191,7 +191,7 @@ namespace Unit {
             return computeUnitGaussianDensityCached(this, props, this.props.gaussianDensities, ctx, webgl);
         }
 
-        constructor(id: number, invariantId: number, model: Model, elements: StructureElement.Set, conformation: SymmetryOperator.ArrayMapping, props: AtomicProperties) {
+        constructor(id: number, invariantId: number, model: Model, elements: StructureElement.Set, conformation: SymmetryOperator.ArrayMapping<ElementIndex>, props: AtomicProperties) {
             this.id = id;
             this.invariantId = invariantId;
             this.model = model;
@@ -233,7 +233,7 @@ namespace Unit {
         readonly invariantId: number;
         readonly elements: StructureElement.Set;
         readonly model: Model;
-        readonly conformation: SymmetryOperator.ArrayMapping;
+        readonly conformation: SymmetryOperator.ArrayMapping<ElementIndex>;
 
         readonly coarseElements: CoarseElements;
         readonly coarseConformation: C;
@@ -280,7 +280,7 @@ namespace Unit {
             return computeUnitGaussianDensityCached(this as Unit.Spheres | Unit.Gaussians, props, this.props.gaussianDensities, ctx, webgl); // TODO get rid of casting
         }
 
-        constructor(id: number, invariantId: number, model: Model, kind: K, elements: StructureElement.Set, conformation: SymmetryOperator.ArrayMapping, props: CoarseProperties) {
+        constructor(id: number, invariantId: number, model: Model, kind: K, elements: StructureElement.Set, conformation: SymmetryOperator.ArrayMapping<ElementIndex>, props: CoarseProperties) {
             this.kind = kind;
             this.id = id;
             this.invariantId = invariantId;
@@ -309,7 +309,7 @@ namespace Unit {
         };
     }
 
-    function createCoarse<K extends Kind.Gaussians | Kind.Spheres>(id: number, invariantId: number, model: Model, kind: K, elements: StructureElement.Set, conformation: SymmetryOperator.ArrayMapping, props: CoarseProperties): Unit {
+    function createCoarse<K extends Kind.Gaussians | Kind.Spheres>(id: number, invariantId: number, model: Model, kind: K, elements: StructureElement.Set, conformation: SymmetryOperator.ArrayMapping<ElementIndex>, props: CoarseProperties): Unit {
         return new Coarse(id, invariantId, model, kind, elements, conformation, props) as any as Unit /** lets call this an ugly temporary hack */;
     }
 
diff --git a/src/mol-model/structure/structure/util/boundary.ts b/src/mol-model/structure/structure/util/boundary.ts
index b90370614883b4518fb361814074a6696bb74090..f81d74b869f2010c7e6306196553932cfb156c2f 100644
--- a/src/mol-model/structure/structure/util/boundary.ts
+++ b/src/mol-model/structure/structure/util/boundary.ts
@@ -14,7 +14,7 @@ import { ElementIndex } from '../../model/indexing';
 
 export type Boundary = { box: Box3D, sphere: Sphere3D }
 
-function computeElementsPositionBoundary(elements: SortedArray<ElementIndex>, position: SymmetryOperator.CoordinateMapper): Boundary {
+function computeElementsPositionBoundary(elements: SortedArray<ElementIndex>, position: SymmetryOperator.CoordinateMapper<ElementIndex>): Boundary {
     const min = Vec3.create(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE)
     const max = Vec3.create(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE)
     const center = Vec3.zero()
diff --git a/src/mol-repr/structure/visual/nucleotide-block-mesh.ts b/src/mol-repr/structure/visual/nucleotide-block-mesh.ts
index 8e5188611682aa9e0f533e9cde7da22311997263..b3be2492c664406176724afa7772aeddb26c877b 100644
--- a/src/mol-repr/structure/visual/nucleotide-block-mesh.ts
+++ b/src/mol-repr/structure/visual/nucleotide-block-mesh.ts
@@ -4,7 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { Unit, Structure } from 'mol-model/structure';
+import { Unit, Structure, ElementIndex } from 'mol-model/structure';
 import { UnitsVisual } from '../representation';
 import { Vec3, Mat4 } from 'mol-math/linear-algebra';
 import { Segmentation } from 'mol-data/int';
@@ -71,7 +71,7 @@ async function createNucleotideBlockMesh(ctx: VisualContext, unit: Unit, structu
             if (isNucleic(moleculeType)) {
                 const parentId = modifiedResidues.parentId.get(compId)
                 if (parentId !== undefined) compId = parentId
-                let idx1 = -1, idx2 = -1, idx3 = -1, idx4 = -1, idx5 = -1, idx6 = -1
+                let idx1: ElementIndex | -1 = -1, idx2: ElementIndex | -1 = -1, idx3: ElementIndex | -1 = -1, idx4: ElementIndex | -1 = -1, idx5: ElementIndex | -1 = -1, idx6: ElementIndex | -1 = -1
                 let width = 4.5, height = 4.5, depth = 2.5 * sizeFactor
 
                 if (isPurinBase(compId)) {
diff --git a/src/mol-theme/color/cross-link.ts b/src/mol-theme/color/cross-link.ts
index 74b36b07ee393fe476c8dd1fdf030714164a9eb6..2db5d32b2089070784049644a7c79f86e71fd836 100644
--- a/src/mol-theme/color/cross-link.ts
+++ b/src/mol-theme/color/cross-link.ts
@@ -28,8 +28,8 @@ export type CrossLinkColorThemeProps = PD.Values<typeof CrossLinkColorThemeParam
 
 const distVecA = Vec3.zero(), distVecB = Vec3.zero()
 function linkDistance(link: Link.Location) {
-    link.aUnit.conformation.position(link.aIndex, distVecA)
-    link.bUnit.conformation.position(link.bIndex, distVecB)
+    link.aUnit.conformation.position(link.aUnit.elements[link.aIndex], distVecA)
+    link.bUnit.conformation.position(link.bUnit.elements[link.bIndex], distVecB)
     return Vec3.distance(distVecA, distVecB)
 }