Problem with infer two types from string at same time

Offen
#56,936 11 Kommentare 2 Reaktionen 1 zugewiesene Person Auf GitHub ansehen

@rbuckton arbeitet bereits daran.

Seit 08.1.2024.

Bewertung

Dieses Issue wurde noch nicht bewertet.

Beschreibung

Needs Investigation
🔎 Search Terms

If i want infer two types from string in same time with infer U extends Subtype, I get different results depending on the input string

type Test<T extends string> =  T extends `${infer Rest}${infer D extends Digit}`
  ? `${Rest}[${D}]`
  : T

It can be solved with two consecutive conditions, but it has its price ( in example you can see three different implementations with different result)

🕗 Version & Regression Information
  • This code does not work in versions earlier than 4.7
  • This changed between versions 4.7 and 4.8
  • The result given in the comments to the code corresponds to versions 4.8-5.3
⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.4.0-dev.20240102#code/C4TwDgpgBAIglgczsKBeKAGKAfKBGHKAJkIGZCAWQgVkIDZCB2QgDkIE4AoTgeh6jgA7AGYQATlAA2AQwDOKACaJkUAGRQxEeVAD2wqPLFCEAwbsHQAxjsFLgcG51CQoAFS3AA+ngA8rqBAAHsAQtrJQAAYAJADeggCuALYARuIAvhEAfGhuAcGhCuHRMUKiEgBKHmmxpeKweSFhsMrAGZwAkAD8UADalfIANLAAuh0AXFAWAG51fFB+DQVFsQkp6ZkRUGBiOiGWIQpQ8eGpwjqa3HO1EpraegbARoIIQ8AAFqGmZVJyii0GEGstigQLsDkETnA0Hc8k8RAWQUahUiKySqTEGWy6H8iKWKJKIjq-VasXgSFaEQ63Rx+SaxWJ1QJ3xgiyaZOQbXaXV6xKGMFGXIm01m-GEcDE2lByHBWx2ewORxOEDOF3aQogMwkcwRtORxVW6LSG1lu0BCuOUFO5wgl341x+2iU5NeHzM9tuKHuhmMANBIJsYMczmhHk8pB1SOWcTR6SyORpkfx3uejPtLNxbJanOprL1NUJFSqpM53L6Hj5ArVkw1IqgYolKCl9hsJvlEEOFqtqvVmqg2oTeP1MYxxu2pv27cVluV1u4wagIVhCmkwGk3hyAHI8Bg8BvIS5F15l6u4Zvt3v54fPMe1+R0FuL1CF6Gb54qPeMI+Dy+V2vaPev2gK9bniSQvAIdAei3T8hjwUZL1DECwNPSCHyGDB4KfYCtFArw716DcN1gzDv1hJCvHfAiiMwEigMQnDkP-atNTnLDQzwCC3HYnwr1fPBsjmeILECSAJwUHtxH3OjYTwEhsW43jfzhAT+B0ABrCYoN3dDaOfGT8JhcCeJ-E9SBUo5hNEg4JLEKS9PAyjDO8YylyUihzKEoIrPbGzeB4AABYBZAAWi8s1QrEHZbIQmSmKc3xFJPahzPU1jSK8IhOKc+FErXfi+1UjSCPPYi7KvIg5K42EcpMtciBSoqtOojCytDIgDLalyjyUsyCt0RrCNKmKMsczrcrfBrNMGmi-MCkKwv2CKota6q4rG2rPGSvrUpWvCstDcNxvywTLLNHzipg5pyV0q9SEqpzDo2+rtoG7SZuGsMOthR7XNMjzTrEqbqPZYAboO0bvq6683P+hbrKovkWlGPg5tCkTwvEZaPtINbIfGra5h2uY7IAUXR-YIzxR54ggLFOCgBmoAACj8TImYASjQbIByafxugICYiE5jNCnpxnWY5rnchF8JqegfmoEFqBujlxW62kSRZBtUmAEd4g1nwAEEhgAISxKAxZZ1w2c51BudzcJDeV-A1aFh3LYl237ZlqATedgXiE5lWxBptXhA1rW0qsOQtByHoxbJqyfBJvWDavDjXno2RcO8TJMgGBPyeAZPU8kKHZMzsiGIyvOC4ZxOzRL-Wy-T0hK68ciw1rwuk5T5vy4odvPE79z857xu+7T9jqCHzvkrH+ui6bqfqrwWfq9zheoAbinJ5btqiHX7PkPqred+Lveofao+c7Ms+l8v8rB-s4eN9Huvt4f0ur5nl+5+7xevdv63TXn-De-F75AP7rdQ+YDj410gRPYBB025wNvgAz+UCV54WftheBE1EG72Qd9X+eCc7zwLqMIAA

💻 Code
type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

// infer last digit & rest of string in one condition
type Test_1<T extends `${number}`> = T extends `${infer Rest}${infer D extends Digit}`
	? [Rest, D]
	: never // <T extends `${number}>` protected us before

// infer rest of string, then infer last digit second condition
type Test_2<T extends `${number}`> = T extends `${infer Rest}${Digit}`
	? T extends `${Rest}${infer D extends Digit}`
		? [Rest, D]
		: never
	: never // <T extends `${number}>` protected us before

// infer last digit, then infer rest of string second condition
type Test_3<T extends `${number}`> = T extends `${string}${infer D extends Digit}`
	? T extends `${infer Rest}${D}`
		? [Rest, D]
		: never
	: never // <T extends `${number}>` protected us before
🙁 Actual behavior
type test_11 = Test_1<'101'> // unexpected: never
type test_12 = Test_1<'10'> // ok: ['1', 0]
type test_13 = Test_1<'1'> // unexpected: never
type test_14 = Test_1<'0'> // unexpected: never
//@ts-expect-error
type test_15 = Test_1<''> // ok

type test_21 = Test_2<'101'> // ok: ['10', 1]
type test_22 = Test_2<'10'> // ok: ['1', 0]
type test_23 = Test_2<'1'> // ok: ['', 1]
type test_24 = Test_2<'0'> // ok: ['', 0]
//@ts-expect-error
type test_25 = Test_2<''> // ok

type test_31 = Test_3<'101'> // unexpected: ['10', Digit]
type test_32 = Test_3<'10'> // ok: ['1', 0]
type test_33 = Test_3<'1'> // unexpected: ['', Digit]
type test_34 = Test_3<'0'> // unexpected: ['', Digit]
//@ts-expect-error
type test_35 = Test_3<''> // ok
🙂 Expected behavior

Test_1, Test_2 & Test_3 has equal behaviour

Additional information about the issue

No response

Vorherrschende Sprache
Go
Sterne
111k
Forks
14.4k
Ø Merge
1 T. 19 Std.
Gemergte PRs (30 T.)
117

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus microsoft/TypeScript

Alle Issues in microsoft/TypeScript

Ähnliche Issues

Weitere Issues zu Go

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.