```ts
export function addDecimalStrings(a: string, b: string): string {
  // Validate inputs
  if (typeof a !== 'string' || typeof b !== 'string') {
    throw new Error('Both arguments must be strings');
  }
  
  if (a.length === 0 || b.length === 0) {
    throw new Error('Both arguments must be non-empty strings');
  }
  
  // Check for invalid characters
  if (!/^\d+$/.test(a) || !/^\d+$/.test(b)) {
    throw new Error('Both arguments must contain only digits 0-9');
  }
  
  // Handle leading zeros by converting to number and back to string
  // This ensures canonical representation (e.g., "007" becomes "7")
  const numA = BigInt(a);
  const numB = BigInt(b);
  
  // Since we're not allowed to use BigInt for the calculation,
  // we'll implement digit-by-digit addition manually
  
  // Normalize inputs to remove leading zeros but keep at least one digit
  let normalizedA = a.replace(/^0+/, '') || '0';
  let normalizedB = b.replace(/^0+/, '') || '0';
  
  // Prepare arrays for digit-by-digit addition
  const digitsA = normalizedA.split('').reverse();
  const digitsB = normalizedB.split('').reverse();
  
  // Determine the maximum length
  const maxLength = Math.max(digitsA.length, digitsB.length);
  
  let carry = 0;
  const resultDigits: number[] = [];
  
  // Perform digit-by-digit addition
  for (let i = 0; i < maxLength || carry > 0; i++) {
    const digitA = i < digitsA.length ? parseInt(digitsA[i]) : 0;
    const digitB = i < digitsB.length ? parseInt(digitsB[i]) : 0;
    
    const sum = digitA + digitB + carry;
    resultDigits.push(sum % 10);
    carry = Math.floor(sum / 10);
  }
  
  // Convert back to string
  let result = resultDigits.reverse().join('');
  
  // Ensure canonical representation (no leading zeros)
  result = result.replace(/^0+/, '') || '0';
  
  return result;
}
```