TypeScript Version: 3.4.0-dev.201xxxxx
Search Terms:
Code
function test<T extends { a: string, b: string }>(obj: T) {
const test: Partial<T> = { a: 'a', b: 'b' }; // TS2322 type '{ a: string, b: string }' is not assignable to type 'Partial<T>'.
}
Expected behavior:
no error
Actual behavior:
TS2322 error
Playground Link:
Related Issues:
This would be unsound if you instantiated T with a more specific type.
function test<T extends { a: string, b: string }>(obj: T) {
const test: Partial<T> = { a: 'a', b: 'b' };
return test.a
}
const result: 'b' | undefined = test({ a: 'b', b: 'a'} as const); // actually 'a'
@jack-williams what are you mean?
function test<T extends { a: string, b: string }>(obj: T) {
const test: Partial<T> = { a: 'a', b: 'b' } as T; // force no error.
return test.a
}
const result: 'b' | undefined = test({ a: 'b', b: 'a'} as const); // TS2322: Type '"a" | undefined' is not assignable to type '"b" | undefined'. Type '"a"' is not assignable to type '"b | undefined"'.
Can you create a playground link that shows that error?
@vipcxj What @jack-williams is trying to say is that the assignment doesn't work because the generic T parameter might be more specific. For example, if it worked you would be able to write code like this: http://www.typescriptlang.org/play/#code/JYOwLgpgTgZghgYwgAgEJwM4oN7LgLmQzClAHMAaZAI0ONJDOQF8BYAKA5gFcQExgAexDJIxADwAVZBAAekEABMMaTBAB8ACkHUAVoUkBKA8mwdkyKBDDcoI3AWQByOE6q1n1JywDcHNpzsoJCwiCgAwoIAtgAOADZyMvIQSiroWKbmyIJgABbQdCTk-hwcihAIcXBWyAlgyAjR8XIAanBx3BCEkbEJshx1eCA5+VA9zbJtHSgAvKIQxJqNva3tnYYcQA
Search Terms: π¦π¦
Duplicate of #13442, #21196, etc
type Mix<B, T extends B> = { [K in keyof T]: K extends keyof B ? B[K] : T[K] }
type PMix<B, T extends B> = { [K in keyof T]?: K extends keyof B ? B[K] : T[K] }
type Base = { a: string, b: string }
interface EX extends Base {
a: '1';
}
const e: Mix<Base, EX> = { a: '3', b: '' }
function test<T extends Base>(obj: T): string | undefined {
const test: PMix<Base, T> = { a: 'a', b: 'b' }; // still not work here.
return test.a
}
let result = test({ a: 'b', b: 'a'} as const); // result is string | undefined now.
result = '3'
@vipcxj It won't work, the assignment doesn't work for the same reason I mentioned above. Here is your modified example...
http://www.typescriptlang.org/play/#code/C4TwDgpgBAsglgDwDwCEA0UAqUIOBAOwBMBnKFAPigF4oBvKAbQGko4CoBrCEAewDMsAXQBcUVrnzEy3PoJRQA-ORZCoYzKqgBfALAAoUJCgAFeMnRYceQqXJVaDFmw6yBwxWIk3pXHu4VlFC0NLT19AyNoFABDEmhHKBixEmAAJ3YAcwwAIxT0rJ0Ddnw0-hiAY2gAUQANayk7WPj6AygksQByAEZOgG4DcIreAlScMXNUOIgMOod6DqhOgGZO3K7OnSgDfgBXAgrgOBGofFSkbElbMmaICgAKXhyAKw0ASjEzRCn4jEwqOhtdrDUbAU4QVKfSa3P7zBjJJYxNZQPJLHKbbQDfTtKBpCDAXZpDhnYCDAwAG3xuIhu3JYNoJPu8K66PWiORFS6FWRRC6RGREC6EE62iSZBBYwA9AAqLAACzgZAA7nByeSUdBgHLoJlCBAMhVTuBoNh2OCxvwCNLJW8sZLJVBybxeJwkmColB3J08SRacBkXxdlBnrsxjk0i6TQBlDUVGKh6CB4OhsFxEhwTIECBEAz2hYIzpItmddFbYC8XMO5lo5Gowscrk8vkCoUioA
@Siegrift PMix is another version of Partial, and test return PMix, not T, so test({ a: 'b', b: 'a', c: 'c', d: 'd', e: 'e'}) be assigned to { a?: string, b?: string, c: 'c', d: 'd', e: 'e'} should be ok.
Sorry, you're right. I don't know what is wrong with that code. I created even smaller example, but I don't get why it doesn't typecheck... (@jack-williams do you know why?)
@Siegrift Your example doesn't work because you are still assigning a concrete value to something that is inherently generic. The error is correct here for the same reasons:
const a: "b" | undefined = partial({ a: 'b' as 'b'}).a // no error, 'a' at runtime
@vipcxj Returning a value of type string | undefined does not negate the fact you are assigning to a generic value who's concrete type you do not know, and you do not know who else has a reference to that object (and at what type). TypeScript cannot go back an retroactively allow an assignment because later on the value is used in a potentially consistent way. Only using a generic in an input position and not in an output position is usually wrong.
@jack-williams Thank you very much. I wasn't able to create a counterexample.
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.
@jack-williams please give me a example of PMix.
Most helpful comment
Duplicate of #13442, #21196, etc