Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Primary types not being correclty inferred in return of a function with explicit type check with genrics. #51618

Closed
TramontaG opened this issue Nov 21, 2022 · 5 comments
Labels
Duplicate An existing issue was already created

Comments

@TramontaG
Copy link

TramontaG commented Nov 21, 2022

Bug Report

I think typescript should be able to correclty infer the type of a generic if a primary type check is made inside a function.

🔎 Search Terms

Different subtype of constraint
Primary type

🕗 Version & Regression Information

This happens in the newest version of typescript

⏯ Playground Link

Playground link with relevant code

💻 Code

/**
 * Those returns should not be errors
 */
const testFn = <T extends string | number>(val: T): T => {
	if (typeof val === "number"){
		return 3;
	}
	return "3";
}

/**
 * I shouldn't have to cast the returns to T
 */
const testFn2 = <T extends string | number>(val: T): T => {
	if (typeof val === "number"){
		return 3 as T;
	}
	return "3" as T;
}

const someNumber = testFn(3);
const someString = testFn("3");

🙁 Actual behavior

Error in both returns of testFn even though they both are ok according to the T generic.
someNumber is corectly infered as number, someString is correctly inferred as string and error properly throws an error because the argument doesnt follow the constraints of the generic T

I can correct this by casting the returns to T but it seems like it should not be necessary. It feels like a workaround.

🙂 Expected behavior

No errors in the testFn returns.

@fatcerberus
Copy link

fatcerberus commented Nov 21, 2022

#33014 is related. Narrowing a value of type T doesn't narrow T and doing so isn't sound in general.

Duplicate of #13995. See @jcalz' remarks below.

@MartinJohns
Copy link
Contributor

Error in both returns of testFn even though they both are ok according to the T generic.

According to your generic the type argument T can be string, but your function attempts to return a number.

@jcalz
Copy link
Contributor

jcalz commented Nov 21, 2022

Even without the re-constraining of T this would fail, because testFn(0) returns a value of type 0, but you're actually returning 3. So ["oops"][testFn(0)].toUpperCase(); compiles but throws a runtime error. So the example here would need to be improved before it would even be a duplicate of #33014.

(and @fatcerberus #13995 is apparently not the issue here)

@fatcerberus
Copy link

#13995 is apparently not the issue here

Hmm... huh. It appears you're right. I swear there was another issue about this besides #33014, though...

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Nov 30, 2022
@RyanCavanaugh
Copy link
Member

Half #33014, half working as intended (because even with that, T could be 0 as noted).

@RyanCavanaugh RyanCavanaugh closed this as not planned Won't fix, can't repro, duplicate, stale Nov 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

5 participants