TS migration. #2288. (#2328)

* Added TS. Updated build and linting config. Added types.

* [ts-migrate][.] Rename files from JS/JSX to TS/TSX

Co-authored-by: ts-migrate <>

* [ts-migrate][.] Run TS Migrate

Co-authored-by: ts-migrate <>

* Corrected files mangled by ts-migrate.

* Updated lint config, minor linting.

* Re-enabled Husky.

* Updated tests and config.

* Reverted webpack devtool config.

* Removed obsolete snapshots.

* Added annotations snap.

* Updated tsconfig includes wrt linting.

* Removed ts-migrate.

Co-authored-by: Timmy Huang <tihuan@users.noreply.github.com>
This commit is contained in:
Mim Hastie
2021-07-26 20:18:17 +00:00
committed by GitHub
co-authored by ts-migrate Timmy Huang
parent 7328cbdbd5
commit 934cc5c69b
206 changed files with 4719 additions and 2085 deletions
@@ -17,6 +17,7 @@ In addition, the current state management only allows for
categorical annotations to be writable.
*/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'schema' implicitly has an 'any' type.
export function isCategoricalAnnotation(schema, name) {
/*
we treat any string, categorical or boolean as a categorical.
@@ -28,6 +29,7 @@ export function isCategoricalAnnotation(schema, name) {
return type === "string" || type === "boolean" || type === "categorical";
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'schema' implicitly has an 'any' type.
export function isContinuousAnnotation(schema, name) {
/*
Return true/false/undefined
@@ -38,14 +40,17 @@ export function isContinuousAnnotation(schema, name) {
return !(type === "string" || type === "boolean" || type === "categorical");
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'schema' implicitly has an 'any' type.
function _isUserAnnotation(schema, name) {
return schema.annotations.obsByName[name]?.writable || false;
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
export function isUserAnnotation(annoMatrix, name) {
return _isUserAnnotation(annoMatrix.schema, name);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'df' implicitly has an 'any' type.
export function allHaveLabelByMask(df, colName, label, mask) {
// return true if all rows as indicated by mask have the colname set to label.
// False if not.
@@ -63,6 +68,7 @@ export function allHaveLabelByMask(df, colName, label, mask) {
}
const legalCharacters = /^(\w|[ .()-])+$/;
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'name' implicitly has an 'any' type.
export function annotationNameIsErroneous(name) {
/*
Validate the name - return:
@@ -12,7 +12,12 @@ import { range } from "../range";
given a color mode & accessor, generate an annoMatrix query that will
fulfill it
*/
export function createColorQuery(colorMode, colorByAccessor, schema, genesets) {
export function createColorQuery(
colorMode: any,
colorByAccessor: any,
schema: any,
genesets: any
) {
if (!colorMode || !colorByAccessor || !schema || !genesets) return null;
switch (colorMode) {
@@ -61,7 +66,7 @@ export function createColorQuery(colorMode, colorByAccessor, schema, genesets) {
}
}
function _defaultColors(nObs) {
function _defaultColors(nObs: any) {
const defaultCellColor = parseRGB(globals.defaultCellColor);
return {
rgb: new Array(nObs).fill(defaultCellColor),
@@ -84,15 +89,16 @@ Returns:
}
*/
function _createColorTable(
colorMode,
colorByAccessor,
colorByData,
schema,
colorMode: any,
colorByAccessor: any,
colorByData: any,
schema: any,
userColors = null
) {
switch (colorMode) {
case "color by categorical metadata": {
const data = colorByData.col(colorByAccessor).asArray();
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
if (userColors && colorByAccessor in userColors) {
return createUserColors(data, colorByAccessor, schema, userColors);
}
@@ -126,25 +132,34 @@ export const createColorTable = memoize(_createColorTable);
* - scale: function which given label returns d3 color scale for label
* Order doesn't matter - everything is keyed by label value.
*/
export function loadUserColorConfig(userColors) {
export function loadUserColorConfig(userColors: any) {
const convertedUserColors = {};
Object.keys(userColors).forEach((category) => {
const [colors, scaleMap] = Object.keys(userColors[category]).reduce(
(acc, label) => {
const color = parseRGB(userColors[category][label]);
// @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
acc[0][label] = color;
// @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
acc[1][label] = d3.rgb(255 * color[0], 255 * color[1], 255 * color[2]);
return acc;
},
[{}, {}]
);
const scale = (label) => scaleMap[label];
// @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
const scale = (label: any) => scaleMap[label];
// @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
convertedUserColors[category] = { colors, scale };
});
return convertedUserColors;
}
function _createUserColors(data, colorAccessor, schema, userColors) {
function _createUserColors(
data: any,
colorAccessor: any,
schema: any,
userColors: any
) {
const { colors, scale: scaleByLabel } = userColors[colorAccessor];
const rgb = createRgbArray(data, colors);
@@ -152,14 +167,18 @@ function _createUserColors(data, colorAccessor, schema, userColors) {
// See createColorsByCategoricalMetadata() for another example.
const { categories } = schema.annotations.obsByName[colorAccessor];
const categoryMap = new Map();
categories.forEach((label, idx) => categoryMap.set(idx, label));
const scale = (idx) => scaleByLabel(categoryMap.get(idx));
categories.forEach((label: any, idx: any) => categoryMap.set(idx, label));
const scale = (idx: any) => scaleByLabel(categoryMap.get(idx));
return { rgb, scale };
}
const createUserColors = memoize(_createUserColors);
function _createColorsByCategoricalMetadata(data, colorAccessor, schema) {
function _createColorsByCategoricalMetadata(
data: any,
colorAccessor: any,
schema: any
) {
const { categories } = schema.annotations.obsByName[colorAccessor];
const scale = d3
@@ -167,7 +186,7 @@ function _createColorsByCategoricalMetadata(data, colorAccessor, schema) {
.domain([0, categories.length]);
/* pre-create colors - much faster than doing it for each obs */
const colors = categories.reduce((acc, cat, idx) => {
const colors = categories.reduce((acc: any, cat: any, idx: any) => {
acc[cat] = parseRGB(scale(idx));
return acc;
}, {});
@@ -179,7 +198,7 @@ const createColorsByCategoricalMetadata = memoize(
_createColorsByCategoricalMetadata
);
function createRgbArray(data, colors) {
function createRgbArray(data: any, colors: any) {
const rgb = new Array(data.length);
for (let i = 0, len = data.length; i < len; i += 1) {
const label = data[i];
@@ -188,7 +207,7 @@ function createRgbArray(data, colors) {
return rgb;
}
function _createColorsByContinuousMetadata(data, min, max) {
function _createColorsByContinuousMetadata(data: any, min: any, max: any) {
const colorBins = 100;
const scale = d3
.scaleQuantile()
@@ -35,11 +35,11 @@ Remember that option values can be ANY js type, except undefined/null.
}
}
*/
function topNCategories(colSchema, summary, N) {
function topNCategories(colSchema: any, summary: any, N: any) {
/* return top N categories by occurrences in the data */
const { categories: allCategories } = colSchema;
const counts = allCategories.map(
(cat) => summary.categoryCounts.get(cat) ?? 0
(cat: any) => summary.categoryCounts.get(cat) ?? 0
);
if (allCategories.length <= N) {
@@ -47,7 +47,7 @@ function topNCategories(colSchema, summary, N) {
}
const sortIndex = fillRange(new Array(allCategories.length)).sort(
(a, b) => counts[b] - counts[a]
(a: any, b: any) => counts[b] - counts[a]
);
const topNindices = new Set(sortIndex.slice(0, N));
@@ -62,7 +62,7 @@ function topNCategories(colSchema, summary, N) {
return [allCategories, _topNCategories, topNCounts];
}
export function isSelectableCategoryName(schema, name) {
export function isSelectableCategoryName(schema: any, name: any) {
const { index } = schema.annotations.obs;
const colSchema = schema.annotations.obsByName[name];
return (
@@ -72,7 +72,7 @@ export function isSelectableCategoryName(schema, name) {
);
}
export function selectableCategoryNames(schema, names) {
export function selectableCategoryNames(schema: any, names: any) {
/*
return all obs annotation names that are categorical AND have a
"reasonably" small number of categories AND are not the index column.
@@ -80,11 +80,11 @@ export function selectableCategoryNames(schema, names) {
If the initial name list not provided, use everything in the schema.
*/
if (!schema) return [];
if (!names) names = schema.annotations.obs.columns.map((c) => c.name);
return names.filter((name) => isSelectableCategoryName(schema, name));
if (!names) names = schema.annotations.obs.columns.map((c: any) => c.name);
return names.filter((name: any) => isSelectableCategoryName(schema, name));
}
export function createCategorySummaryFromDfCol(dfCol, colSchema) {
export function createCategorySummaryFromDfCol(dfCol: any, colSchema: any) {
const N = globals.maxCategoricalOptionsToDisplay;
const { writable: isUserAnno } = colSchema;
@@ -99,7 +99,9 @@ export function createCategorySummaryFromDfCol(dfCol, colSchema) {
categoryValues,
categoryValueCounts,
] = topNCategories(colSchema, summary, N);
const categoryValueIndices = new Map(categoryValues.map((v, i) => [v, i]));
const categoryValueIndices = new Map(
categoryValues.map((v: any, i: any) => [v, i])
);
const numCategoryValues = categoryValueIndices.size;
const isTruncated = categoryValues.length < summary.numCategories;
@@ -114,11 +116,11 @@ export function createCategorySummaryFromDfCol(dfCol, colSchema) {
};
}
export function createCategoricalSelection(names) {
return fromEntries(names.map((name) => [name, new Map()]));
export function createCategoricalSelection(names: any) {
return fromEntries(names.map((name: any) => [name, new Map()]));
}
export function pruneVarDataCache(varData, needed) {
export function pruneVarDataCache(varData: any, needed: any) {
/*
Remove any unneeded columns from the varData dataframe. Will only
prune / remove if the total column count exceeds VarDataCacheLowWatermark
@@ -17,7 +17,7 @@ Matrix flatbuffer decoding support. See fbs/matrix.fbs
/*
Decode NetEncoding.TypedArray
*/
function decodeTypedArray(uType, uValF, inplace = false) {
function decodeTypedArray(uType: any, uValF: any, inplace = false) {
if (uType === NetEncoding.TypedArray.NONE) {
return null;
}
@@ -48,7 +48,7 @@ Returns: object containing decoded Matrix:
colIdx: []|null
}
*/
export function decodeMatrixFBS(arrayBuffer, inplace = false) {
export function decodeMatrixFBS(arrayBuffer: any, inplace = false) {
const bb = new flatbuffers.ByteBuffer(new Uint8Array(arrayBuffer));
const matrix = NetEncoding.Matrix.getRootAsMatrix(bb);
@@ -79,7 +79,7 @@ export function decodeMatrixFBS(arrayBuffer, inplace = false) {
};
}
function encodeTypedArray(builder, uType, uData) {
function encodeTypedArray(builder: any, uType: any, uData: any) {
const uTypeName = NetEncoding.TypedArray[uType];
const ArrayType = NetEncoding[uTypeName];
const dv = ArrayType.createDataVector(builder, uData);
@@ -88,7 +88,7 @@ function encodeTypedArray(builder, uType, uData) {
return builder.endObject();
}
export function encodeMatrixFBS(df) {
export function encodeMatrixFBS(df: any) {
/*
encode the dataframe as an FBS Matrix
*/
@@ -99,6 +99,7 @@ export function encodeMatrixFBS(df) {
}
const shape = df.dims;
// @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 1.
const utf8Encoder = new TextEncoder("utf-8");
const builder = new flatbuffers.Builder(1024);
@@ -107,9 +108,9 @@ export function encodeMatrixFBS(df) {
let encColumns;
if (shape[0] > 0 && shape[1] > 0) {
const columns = df.columns().map((col) => col.asArray());
const columns = df.columns().map((col: any) => col.asArray());
const cols = columns.map((carr) => {
const cols = columns.map((carr: any) => {
let uType;
let tarr;
if (isTypedArray(carr)) {
@@ -168,7 +169,7 @@ export function encodeMatrixFBS(df) {
return builder.asUint8Array();
}
function promoteTypedArray(o) {
function promoteTypedArray(o: any) {
/*
Decide what internal data type to use for the data returned from
the server.
@@ -200,7 +201,7 @@ function promoteTypedArray(o) {
return new TypedArrayCtor(o);
}
export function matrixFBSToDataframe(arrayBuffers) {
export function matrixFBSToDataframe(arrayBuffers: any) {
/*
Convert array of Matrix FBS to a Dataframe.
@@ -216,19 +217,19 @@ export function matrixFBSToDataframe(arrayBuffers) {
arrayBuffers = [arrayBuffers];
}
if (arrayBuffers.length === 0) {
return Dataframe.Dataframe.empty();
return (Dataframe as any).Dataframe.empty();
}
const fbs = arrayBuffers.map((ab) => decodeMatrixFBS(ab, true)); // leave in place
const fbs = arrayBuffers.map((ab: any) => decodeMatrixFBS(ab, true)); // leave in place
/* check that all FBS have same row dimensionality */
const { nRows } = fbs[0];
fbs.forEach((b) => {
fbs.forEach((b: any) => {
if (b.nRows !== nRows)
throw new Error("FBS with inconsistent dimensionality");
});
const columns = fbs
.map((fb) =>
fb.columns.map((c) => {
.map((fb: any) =>
fb.columns.map((c: any) => {
if (isFpTypedArray(c) || Array.isArray(c)) return c;
return promoteTypedArray(c);
})
@@ -236,10 +237,13 @@ export function matrixFBSToDataframe(arrayBuffers) {
.flat();
// colIdx may be TypedArray or Array
const colIdx = fbs
.map((b) => (Array.isArray(b.colIdx) ? b.colIdx : Array.from(b.colIdx)))
.map((b: any) =>
Array.isArray(b.colIdx) ? b.colIdx : Array.from(b.colIdx)
)
.flat();
const nCols = columns.length;
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
const df = new Dataframe([nRows, nCols], columns, null, new KeyIndex(colIdx));
return df;
}
@@ -15,25 +15,25 @@ System wide schema assumptions:
- schema will be internally self-consistent (eg, index matches columns)
*/
export function indexEntireSchema(schema) {
export function indexEntireSchema(schema: any) {
/* Index schema for ease of use */
schema.annotations.obsByName = fromEntries(
schema.annotations?.obs?.columns?.map((v) => [v.name, v]) ?? []
schema.annotations?.obs?.columns?.map((v: any) => [v.name, v]) ?? []
);
schema.annotations.varByName = fromEntries(
schema.annotations?.var?.columns?.map((v) => [v.name, v]) ?? []
schema.annotations?.var?.columns?.map((v: any) => [v.name, v]) ?? []
);
schema.layout.obsByName = fromEntries(
schema.layout?.obs?.map((v) => [v.name, v]) ?? []
schema.layout?.obs?.map((v: any) => [v.name, v]) ?? []
);
schema.layout.varByName = fromEntries(
schema.layout?.var?.map((v) => [v.name, v]) ?? []
schema.layout?.var?.map((v: any) => [v.name, v]) ?? []
);
return schema;
}
function _copyObsAnno(schema) {
function _copyObsAnno(schema: any) {
/* redux copy conventions - WARNING, only for modifying obs annotations */
return {
...schema,
@@ -44,7 +44,7 @@ function _copyObsAnno(schema) {
};
}
function _copyObsLayout(schema) {
function _copyObsLayout(schema: any) {
return {
...schema,
layout: {
@@ -54,36 +54,37 @@ function _copyObsLayout(schema) {
};
}
function _reindexObsAnno(schema) {
function _reindexObsAnno(schema: any) {
/* reindex obs annotations ONLY */
schema.annotations.obsByName = fromEntries(
schema.annotations.obs.columns.map((v) => [v.name, v])
schema.annotations.obs.columns.map((v: any) => [v.name, v])
);
return schema;
}
function _reindexObsLayout(schema) {
function _reindexObsLayout(schema: any) {
schema.layout.obsByName = fromEntries(
schema.layout.obs.map((v) => [v.name, v])
schema.layout.obs.map((v: any) => [v.name, v])
);
return schema;
}
export function removeObsAnnoColumn(schema, name) {
export function removeObsAnnoColumn(schema: any, name: any) {
const newSchema = _copyObsAnno(schema);
newSchema.annotations.obs.columns = schema.annotations.obs.columns.filter(
(v) => v.name !== name
(v: any) => v.name !== name
);
return _reindexObsAnno(newSchema);
}
export function addObsAnnoColumn(schema, name, defn) {
// @ts-expect-error ts-migrate(6133) FIXME: 'name' is declared but its value is never read.
export function addObsAnnoColumn(schema: any, name: any, defn: any) {
const newSchema = _copyObsAnno(schema);
newSchema.annotations.obs.columns.push(defn);
return _reindexObsAnno(newSchema);
}
export function removeObsAnnoCategory(schema, name, category) {
export function removeObsAnnoCategory(schema: any, name: any, category: any) {
/* remove a category from a categorical annotation */
const categories = schema.annotations.obsByName[name]?.categories;
if (!categories)
@@ -99,7 +100,7 @@ export function removeObsAnnoCategory(schema, name, category) {
return newSchema;
}
export function addObsAnnoCategory(schema, name, category) {
export function addObsAnnoCategory(schema: any, name: any, category: any) {
/* add a category to a categorical annotation */
const categories = schema.annotations.obsByName[name]?.categories;
if (!categories)
@@ -119,16 +120,16 @@ export function addObsAnnoCategory(schema, name, category) {
return newSchema;
}
export function addObsLayout(schema, layout) {
export function addObsLayout(schema: any, layout: any) {
/* add or replace a layout */
const newSchema = _copyObsLayout(schema);
newSchema.layout.obs.push(layout);
return _reindexObsLayout(newSchema);
}
export function removeObsLayout(schema, name) {
export function removeObsLayout(schema: any, name: any) {
/* remove a layout */
const newSchema = _copyObsLayout(schema);
newSchema.layout.obs = schema.layout.obs.filter((v) => v.name !== name);
newSchema.layout.obs = schema.layout.obs.filter((v: any) => v.name !== name);
return _reindexObsLayout(newSchema);
}
@@ -38,6 +38,7 @@ Views can be interogated for their type with the following:
import { clip, isubsetMask, isubset } from "../../annoMatrix";
import { memoize } from "../dataframe/util";
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
export function _clipAnnoMatrix(annoMatrix, min, max) {
/*
clip the annoMatrix.
@@ -47,6 +48,7 @@ export function _clipAnnoMatrix(annoMatrix, min, max) {
: clip(annoMatrix, min, max);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
export function _userSubsetAnnoMatrix(annoMatrix, mask) {
/*
user-requested row subset of annoMatrix, to be added on top of any
@@ -61,12 +63,14 @@ export function _userSubsetAnnoMatrix(annoMatrix, mask) {
annoMatrix.userFlags.isUserSubsetView = true;
if (clipRange) {
// @ts-expect-error ts-migrate(2556) FIXME: Expected 3 arguments, but got 1 or more.
annoMatrix = clip(annoMatrix, ...clipRange);
}
return annoMatrix;
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
export function _userResetSubsetAnnoMatrix(annoMatrix) {
/*
Reset/remove all user-requested subsets. Do not remove clip or embedding subset.
@@ -85,12 +89,14 @@ export function _userResetSubsetAnnoMatrix(annoMatrix) {
/* re-apply the clip, if any */
if (clipRange) {
// @ts-expect-error ts-migrate(2556) FIXME: Expected 3 arguments, but got 1 or more.
annoMatrix = clip(annoMatrix, ...clipRange);
}
return annoMatrix;
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
export function _setEmbeddingSubset(annoMatrix, embeddingDf) {
/*
Set the embedding subset view. Only create a subset view for the embedding
@@ -124,12 +130,14 @@ export function _setEmbeddingSubset(annoMatrix, embeddingDf) {
/* re-apply clip, if needed */
if (clipRange) {
// @ts-expect-error ts-migrate(2556) FIXME: Expected 3 arguments, but got 1 or more.
annoMatrix = clip(annoMatrix, ...clipRange);
}
return annoMatrix;
}
// @ts-expect-error ts-migrate(6133) FIXME: 'baseRowIndex' is declared but its value is never ... Remove this comment to see the full error message
function _getEmbeddingRowOffsets(baseRowIndex, embeddingDf) {
/*
given a dataframe containing an embedding:
@@ -155,6 +163,7 @@ function _getEmbeddingRowOffsets(baseRowIndex, embeddingDf) {
return offsets.subarray(0, numOffsets);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'embeddingDf' implicitly has an 'any' ty... Remove this comment to see the full error message
export function _getDiscreteCellEmbeddingRowIndex(embeddingDf) {
const idx = _getEmbeddingRowOffsets(embeddingDf.rowIndex, embeddingDf);
if (idx === null) return embeddingDf.rowIndex;
@@ -162,9 +171,11 @@ export function _getDiscreteCellEmbeddingRowIndex(embeddingDf) {
}
export const getDiscreteCellEmbeddingRowIndex = memoize(
_getDiscreteCellEmbeddingRowIndex,
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'df' implicitly has an 'any' type.
(df) => df.__id
);
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
export function getEmbSubsetView(annoMatrix) {
/* if there is an embedding subset in the view stack, return it. Falsish if not. */
while (annoMatrix.isView) {