Problem with infer two types from string at same time

Đang mở
#56,936 11 bình luận 2 reaction 1 người được giao Xem trên GitHub

@rbuckton đang làm issue này rồi.

Từ ngày 8/1/2024.

Đánh giá

Issue này chưa được đánh giá.

Mô tả

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

Ngôn ngữ chính
Go
Star
111k
Fork
14.4k
Merge trung bình
1 ngày 19 giờ
Pull request đã merge (30 ngày)
117

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của microsoft/TypeScript

Tất cả issue của microsoft/TypeScript

Issue tương tự

Thêm issue về Go

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.