diff --git a/src/common/type/utils.ts b/src/common/type/utils.ts index be030478..21d91d5a 100644 --- a/src/common/type/utils.ts +++ b/src/common/type/utils.ts @@ -122,10 +122,11 @@ export function collectionElementType(type: Readonly): Type | undefined { return undefined; } -export function isValidType(t: any): t is Readonly { - if (typeof t === 'string') - return PRIMITIVE_TYPES.includes(t as PrimitiveType); - if (typeof t !== 'object') return false; +export function isValidType(t: unknown): t is Readonly { + const isObject = typeof t === 'object' && t !== null; + if (typeof t === 'string' || (isObject && 'type' in t)) + return PRIMITIVE_TYPES.includes((isObject ? t.type : t) as PrimitiveType); + if (!isObject) return false; if (!('kind' in t)) return false; return ( t.kind === 'signature' || diff --git a/src/compute-engine/boxed-expression/utils.ts b/src/compute-engine/boxed-expression/utils.ts index 30410f84..55c90bf0 100644 --- a/src/compute-engine/boxed-expression/utils.ts +++ b/src/compute-engine/boxed-expression/utils.ts @@ -12,6 +12,8 @@ import { DEFINITIONS_INEQUALITIES } from '../latex-syntax/dictionary/definitions import { MACHINE_PRECISION } from '../numerics/numeric'; import { Type } from '../../common/type/types'; +import { isValidType } from '../../common/type/utils'; +import { isSubtype } from '../../common/type/subtype'; export function isBoxedExpression(x: unknown): x is BoxedExpression { return typeof x === 'object' && x !== null && 'engine' in x; @@ -182,17 +184,26 @@ export function normalizeFlags( return result as NumericFlags; } -export function isSymbolDefinition(def: any): def is SymbolDefinition { +export function isSymbolDefinition(def: unknown): def is SymbolDefinition { if (def === undefined || def === null || typeof def !== 'object') return false; if (isBoxedExpression(def)) return false; - if ('value' in def || 'constant' in def || 'inferred' in def) { - if ('type' in def && typeof def.type === 'function') { - throw new Error( - 'The `type` field of a symbol definition should be of type `string`' - ); + if ( + 'type' in def || + 'value' in def || + 'constant' in def || + 'inferred' in def + ) { + if ('type' in def) { + if (!isValidType(def.type)) + throw new Error(`Invalid type: "${def.type}"`); + if (isSubtype('function', def.type)) { + throw new Error( + 'The `type` field of a symbol definition should be of type `string`' + ); + } } if ('signature' in def) { diff --git a/src/compute-engine/compute-engine.ts b/src/compute-engine/compute-engine.ts index 59dbf148..7d036c71 100755 --- a/src/compute-engine/compute-engine.ts +++ b/src/compute-engine/compute-engine.ts @@ -1371,8 +1371,10 @@ export class ComputeEngine implements IComputeEngine { if ( typeof def === 'object' && 'type' in def && - ((typeof def.type === 'string' && isSubtype(def.type, 'function')) || - (def.type && isValidType(def.type))) + !( + (typeof def.type === 'string' && isSubtype(def.type, 'function')) || + (def.type && isValidType(def.type)) + ) ) { throw new Error( `Invalid definition for "${id}": use a FunctionDefinition to define a function or use 'ce.declare("${id}", "function")'`