'Typescript ERROR(2322) typescript failed to narrow the type

I was trying to add a conditional operator to indicate the return type of the function greet, but got the following error message:

Type '`hello! ${T & string}`' is not assignable to type 'T extends string ? string : string[]'. Type 'string' is not assignable to type 'T extends string ? string : string[]'.

Bellow is the screenshots:

codes error messages

Below is the codes, and you can copy it to the Typescript playground to test it.

// Welcome to the TypeScript Playground, this is a website
// which gives you a chance to write, share and learn TypeScript.

// You could think of it in three ways:
//
//  - A location to learn TypeScript where nothing can break
//  - A place to experiment with TypeScript syntax, and share the URLs with others
//  - A sandbox to experiment with different compiler features of TypeScript

const anExampleVariable = "Hello World"
console.log(anExampleVariable)

// To learn more about the language, click above in "Examples" or "What's New".
// Otherwise, get started by removing these comments and the world is your playground.

function isString(val: any): val is string{
    return Object.prototype.toString.call(val) === '[object String]';
}

function greet<T extends string | string[]>(person: T) : T extends string ? string: string[]  {
    if( isString(person) ){
        return `hello! ${person}`;
    } else {
        return person.map(p=>`hello! ${p}`);
    }
}

let greetStr: string = greet('Jhon');
let greetStrAry: string[] = greet(['Jhon', 'Miley']);
console.log(greetStr);
console.log(greetStrAry);


Solution 1:[1]

You can use function overload to workaround the difficulty of saying that person can be either one string or string[], and that the return type should be the same:

function greet(person: string): string;
function greet(person: string[]): string[];
function greet(person: string | string[]): string | string[] {
    if( isString(person) ){
        return `hello! ${person}`;
    } else {
        return person.map(p=>`hello! ${p}`);
    }
}

Demo

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ghybs