```typescript
export function parseSemver(version: string): { major: number; minor: number; patch: number; prerelease: string | null; build: string | null } {
    if (!/^\d+\.\d+\.\d+(\-\w+)?(\+\w+)?$/.test(version)) {
        throw new Error(`Invalid semantic version: ${version}`);
    }

    const parts = version.split('.');
    const major = parseInt(parts[0], 10);
    const minor = parseInt(parts[1], 10);
    const patch = parseInt(parts[2], 10);

    let prerelease: string | null = null;
    let build: string | null = null;

    if (parts.length === 4) {
        [prerelease] = parts.slice(3).filter(part => part !== '');

        if (!/^\w+$/.test(prerelease)) {
            throw new Error(`Invalid prerelease tag in version: ${version}`);
        }
    } else if (parts.length > 4) {
        build = parts.slice(3).join('-');
    }

    return { major, minor, patch, prerelease, build };
}
```