An experimental TypeSpec syntax for Lexicon
57
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix types

authored by danabra.mov and committed by

Tangled e9dc14c6 0c277f30

+22 -10
+22 -10
packages/emitter/src/emitter.ts
··· 48 48 LexCidLink, 49 49 LexRefVariant, 50 50 LexToken, 51 + LexBoolean, 52 + LexInteger, 53 + LexString, 51 54 } from "./types.js"; 52 55 53 56 import { ··· 415 418 // Apply @default decorator if present 416 419 const rawDefault = getDefault(this.program, scalar); 417 420 const defaultValue = this.processDefaultValue(rawDefault); 418 - let defWithDefault: any = { ...scalarDef }; 421 + let defWithDefault: LexObjectProperty = { ...scalarDef }; 419 422 420 423 if (defaultValue !== undefined) { 421 424 // Check if it's a Type (model reference for tokens) ··· 431 434 } else { 432 435 // Validate that the default value matches the type 433 436 this.assertValidValueForType(scalarDef.type, defaultValue, scalar); 434 - defWithDefault = { ...defWithDefault, default: defaultValue }; 437 + // Type-safe narrowing based on both the type discriminator and value type 438 + if (scalarDef.type === "boolean" && typeof defaultValue === "boolean") { 439 + (defWithDefault as LexBoolean).default = defaultValue; 440 + } else if (scalarDef.type === "integer" && typeof defaultValue === "number") { 441 + (defWithDefault as LexInteger).default = defaultValue; 442 + } else if (scalarDef.type === "string" && typeof defaultValue === "string") { 443 + (defWithDefault as LexString).default = defaultValue; 444 + } 435 445 } 436 446 } 437 447 ··· 439 449 if (scalarDef.type === "integer") { 440 450 const minValue = getMinValue(this.program, scalar); 441 451 if (minValue !== undefined) { 442 - (defWithDefault as any).minimum = minValue; 452 + (defWithDefault as LexInteger).minimum = minValue; 443 453 } 444 454 const maxValue = getMaxValue(this.program, scalar); 445 455 if (maxValue !== undefined) { 446 - (defWithDefault as any).maximum = maxValue; 456 + (defWithDefault as LexInteger).maximum = maxValue; 447 457 } 448 458 } 449 459 ··· 474 484 // Apply @default decorator if present 475 485 const rawDefault = getDefault(this.program, union); 476 486 const defaultValue = this.processDefaultValue(rawDefault); 477 - let defWithDefault: any = { ...unionDef }; 487 + let defWithDefault: LexString = { ...unionDef as LexString }; 478 488 479 489 if (defaultValue !== undefined) { 480 490 // Check if it's a Type (model reference for tokens) ··· 517 527 `Use @inline to inline them at usage sites, use @token models for known values, or use string literals.`, 518 528 target: union, 519 529 }); 520 - } else if (unionDef.type === "integer" && (unionDef as any).enum) { 530 + } else if (unionDef.type === "integer" && (unionDef as LexInteger).enum) { 521 531 // Integer enums can also be defs 522 532 const defName = name.charAt(0).toLowerCase() + name.slice(1); 523 533 const description = getDoc(this.program, union); ··· 525 535 // Apply @default decorator if present 526 536 const rawDefault = getDefault(this.program, union); 527 537 const defaultValue = this.processDefaultValue(rawDefault); 528 - let defWithDefault = { ...unionDef }; 538 + let defWithDefault: LexInteger = { ...unionDef as LexInteger }; 529 539 530 540 if (defaultValue !== undefined) { 531 541 if (typeof defaultValue === "number") { ··· 645 655 // Check for default value: property default takes precedence, then union's @default 646 656 let defaultValue: string | number | boolean | undefined; 647 657 if (prop?.defaultValue !== undefined) { 648 - defaultValue = serializeValueAsJson(this.program, prop.defaultValue, prop) as any; 658 + defaultValue = serializeValueAsJson(this.program, prop.defaultValue, prop) as string | number | boolean; 649 659 } else { 650 660 // If no property default, check union's @default decorator 651 661 const rawUnionDefault = getDefault(this.program, unionType); ··· 681 691 // Check for default value: property default takes precedence, then union's @default 682 692 let defaultValue: string | number | boolean | undefined; 683 693 if (prop?.defaultValue !== undefined) { 684 - defaultValue = serializeValueAsJson(this.program, prop.defaultValue, prop) as any; 694 + defaultValue = serializeValueAsJson(this.program, prop.defaultValue, prop) as string | number | boolean; 685 695 } else { 686 696 // If no property default, check union's @default decorator 687 697 const rawUnionDefault = getDefault(this.program, unionType); ··· 1452 1462 const propDefault = serializeValueAsJson(this.program, prop.defaultValue, prop); 1453 1463 1454 1464 // For union defaults that are model references, we need to resolve them for comparison 1455 - let resolvedUnionDefault: string | number | boolean | undefined = unionDefault as any; 1465 + let resolvedUnionDefault: string | number | boolean | undefined; 1456 1466 if (unionDefault && typeof unionDefault === 'object' && 'kind' in unionDefault && unionDefault.kind === 'Model') { 1457 1467 const ref = this.getModelReference(unionDefault as Model, true); 1458 1468 resolvedUnionDefault = ref || undefined; 1469 + } else { 1470 + resolvedUnionDefault = unionDefault as string | number | boolean; 1459 1471 } 1460 1472 1461 1473 // If the union has a different default, or if the property has a default but the union doesn't, error