When a conditional type like NameOrId<T> depends on an unresolved type parameter like the T inside the body of createLabel(), the compiler defers evaluating it.  Such a type is essentially opaque to the compiler, and therefore it is generally unable to verify that a specific value like {id: idOrName} is assignable to it.
When you check typeof idOrName, control flow analysis will narrow the apparent type of idOrName, but this does not narrow the type parameter T itself.  If typeof idOrName === "string", idOrName is now known as being of type string (or T & string), but T is still possibly string | number, and is still an unresolved generic type parameter.
This is a known pain point of TypeScript.  There is an open issue, microsoft/TypeScript#33912, asking for some way to allow control flow analysis to verify assignability to unresolved conditional types, especially as the return value of a function like you want here.  Until and unless that issue is addressed, you'll have to work around it.
Workarounds:
Whenever you have a situation where you are certain that an expression expr is of type Type but the compiler is not, you can always use a type assertion to tell the compiler so: expr as Type, or, in cases where the compiler sees the type expr as completely unrelated to Type, you might have to write expr as any as Type or use some other intermediate assertion.
That would give you this:
function createLabelAssert<T extends string | number>(idOrName: T): NameOrId<T> {
    if (typeof idOrName === "number") {
        return {
            id: idOrName
        } as unknown as NameOrId<T>;
    } else {
        return {
            name: idOrName
        } as unknown as NameOrId<T>;
    }
}
This resolves the errors.  Note that by making an assertion, you are taking responsibility for type safety.  If you modified the typeof idOrName === "number" check to typeof idOrName !== "number", there would still be no compiler error.  But you would be unhappy at runtime.
When you have a function whose return type can't be verified in the implementation, you could do the "moral equivalent" of a type assertion: an overload with a single call signature.  Overload implementations are checked more loosely than regular functions, so you can get the same behavior as a type assertion without having to assert at each return line separately:
// call signature
function createLabel<T extends string | number>(idOrName: T): NameOrId<T>;
// implementation
function createLabel(idOrName: string | number): NameOrId<string | number> {
    if (typeof idOrName === "number") {
        return {
            id: idOrName
        };
    } else {
        return {
            name: idOrName
        };
    }
}
The call signature is the same, but now the implementation signature is just a mapping from string | number to IdLabel | NameLabel.  Again, the compiler won't catch the problem where you check typeof idOrName !== "number" accidentally, so you need to be careful here too.
Playground link to code