```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 valid digits only
  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 can't use BigInt for the actual addition, we'll implement digit-by-digit
  // But for validation purposes, we use BigInt to strip leading zeros properly
  
  // Convert back to strings without leading zeros for canonical form
  const cleanA = numA.toString();
  const cleanB = numB.toString();
  
  // Now perform digit-by-digit addition
  let result = '';
  let carry = 0;
  let i = cleanA.length - 1;
  let j = cleanB.length - 1;
  
  while (i >= 0 || j >= 0 || carry > 0) {
    const digitA = i >= 0 ? parseInt(cleanA[i], 10) : 0;
    const digitB = j >= 0 ? parseInt(cleanB[j], 10) : 0;
    
    const sum = digitA + digitB + carry;
    result = (sum % 10).toString() + result;
    carry = Math.floor(sum / 10);
    
    i--;
    j--;
  }
  
  return result;
}
```