```ts
export function matchSetting(rules: Record<string, string>, name: string): string | null {
  if (typeof rules !== 'object' || typeof name !== 'string') {
    throw new Error('Invalid arguments');
  }

  const isDotted = name.includes('.');
  const isStar = name === '*';

  if (!isDotted && !isStar) {
    return rules[name] ?? null;
  }

  let bestMatch: string | null = null;

  for (const [selector, value] of Object.entries(rules)) {
    if (selector === '*' || selector.endsWith('.*')) {
      const prefix = selector.replace(/.*\./, '');
      if (name.startsWith(prefix) && (!isDotted || name.includes('.'))) {
        bestMatch = value;
      }
    } else if (isDotted && selector === name) {
      bestMatch = value;
    }
  }

  return bestMatch;
}
```